Bug 196134

Summary: telnet hangs due to infinite loop condition
Product: Red Hat Enterprise Linux 3 Reporter: blossom <blossom>
Component: telnetAssignee: Adam Tkac <atkac>
Status: CLOSED CANTFIX QA Contact: Ben Levenson <benl>
Severity: high Docs Contact:
Priority: medium    
Version: 3.0CC: ovasik
Target Milestone: ---   
Target Release: ---   
Hardware: x86_64   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2007-09-03 08:38:06 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:
Bug Depends On:    
Bug Blocks: 274991    

Description blossom 2006-06-21 13:03:26 UTC
Description of problem:
Two telnet client sessions try to contact same server at the same time. One of 
the client will go into a loop consuming large amounts of CPU time.

Version-Release number of selected component (if applicable):
telnet-0.17-26

How reproducible:
It is difficult to reproduce. But the code indicates potential bug


Steps to Reproduce:
netkit-telnet-0.17/telnet/sys_bsd.c in TerminalNewMode()
-----
  if (old < 0 || old > 1) {
#ifdef  USE_TERMIO
        tcgetattr(tin, &tmp_tc);
#endif  /* USE_TERMIO */
        do {
            /*
             * Wait for data to drain, then flush again.
             */
#ifdef  USE_TERMIO
            tcsetattr(tin, TCSADRAIN, &tmp_tc);
#endif  /* USE_TERMIO */
            old = ttyflush(SYNCHing|flushout);
        } while (old < 0 || old > 1);
    }
---------
If there is a problem due to nospace, or interruption inside loop. Telnet 
process hangs with large CPU consmption.

Actual results:
Telnet client process hangs and consumes large CPU.

Expected results:
non working telnet process should come out and should not consume CPU

Additional info:
The code change that would alleviate the problem is in the first code segment - 
the do loop in TerminalNewMode() should be changed to continue only for certain 
errors - new code:

          do {
              /*
               * Wait for data to drain, then flush again.
               */
#ifdef  USE_TERMIO
              tcsetattr(tin, TCSADRAIN, &tmp_tc); #endif  /* USE_TERMIO 
*/
              old = ttyflush(SYNCHing|flushout);
              if (old < 0) {
                  if (! (   (errno == EINTR)
                          || (errno == EAGAIN)
                          || (errno == ENOSPC))) {
                      break;
                  }
              }
          } while (old < 0 || old > 1);

Comment 1 Adam Tkac 2007-09-03 08:38:06 UTC
RHEL 3 is in maintenance stage now so only security bugs are fixed. Moving to
Fedora development (bug #274991)

Adam