Linux 1.2.x, 2.0.x


    'moOd' has found that inetd on (*atleast*) Debian distribution  of
    LiNUX  crashes  when  port  13  (daytime)  /  port  37  (time)  is
    "half-open scanned"..  This seems to be problem with Linux  1.2.x,

    The problem caused by an implementation of Linux kernel - accept()
    returns socket after getting  first SYN (for example,  BSD returns
    socket  only  after  3-way   handshake).  If  your  program   uses
    getpeername() or getsockname() right  after the accept(), it  will
    detect the situation when socket is not valid (because  connection
    was cancelled by RST), but in any other case it has big chances to
    die due SIGPIPE.  So well-written programs aren't affected.

    This bug can also  affect early sendmail versions  (can't remember
    exact version,  something around  8.7.*).   This bug  affects ssh,
    but ssh does fork() right after accept(), so only child dies.

    Half-open scanning means that you:

        1) send SYN
        2) if reply is SYN|ACK, send RST  = port is listening
        3) if reply is RST                = port is not listening

    Most of the new portscanner  include this type of scanning  method
    (scantcp 1.32,  sirc, etc.).   For code  check Phrack  49-07,  the
    `Vengeance` module:

    Aleph  One  gave  following  comment.   The  problem  is two fold.
    First, inetd is dying because it receives a SIGPIPE when it  tries
    to  write  to  the  socket  returned  by  accept since it does not
    install a signal handler for it.  To fix install a signal  handler
    for SIGPIPE.  He belives the latest version of NetKit already does
    this.  Now  you may be  wondering why does  a write to  the socket
    returned by  accept() generates  a SIGPIPE.  This bring  us to the
    second issue. It seems that at least under Linux 2.0.X accept will
    return  a  socket  in  the  received  queue  if  it  is not in the
    SYN_SENT or SYN_RECV state, even when it has not gone through  the
    ESTABLISHED state.  By doing a stealth scan on the port the socket
    goes from the SYN_RECV state to the CLOSED state. When you try  to
    read from such a socket you get a SIGPIPE. The sematics of Linux's
    accept seems to be non-standard.

    This sounds a lot like  the antiquated SYN, RST DoS  problem older
    Linux  inetds  were  vulnerable  to.   Send  a  SYN to an internal
    service, and immediately  follow it up  with a RST  packet.  inetd
    would become unstable and die after the next connection.


    Quick & dirty  workaround would be  to comment out  daytime & time
    services from /etc/inetd.conf  and restart inetd.   However as  it
    seems to be problem with older kernel and older version of NetKit,
    appropriate upgrade will do it.

    The workaround for inetd - put it in "fork() after accept()"  mode
    (some  option  in  command  line).  Another  workaround - put your
    router in  "ip established"  mode (router  will pass  session only
    after connection will be established)