COMMAND

    LPRng

SYSTEMS AFFECTED

    LPRng 3.6.1..15 (at least)

PROBLEM

    Patrick Powell posted  following.  Well,  even in spite  of all of
    efforts, care, and paranoia, he finally dropped the hammer on  his
    foot.   Luckily it  appears that  he spotted  this loophole before
    somebody on the LPRng mailing list did.

    Versions of LPRng-3.6.1-LPRng-3.6.15  installed the 'lpd'  program
    'SETUID root' by default.   The lpd executable should be  OWNED by
    root, but not SETUID root.

    If lpd is SETUID root and executable by users, it is possible  for
    users to append lpd trace  and logging messages to existing  files
    owned by the user/group the lpd process runs as.

    The problem  was discovered  when Lars  Kellogg-Stedman asked  why
    the  'lpd  -L  logfile'  option  required  logfile to exist.  This
    caused Patrick to look at the  code that lpd used to open  the log
    file and he realized that:

    - if the lpd server is not running
     - AND if lpd is installed SETUID root
      - AND if non-root users can execute lpd
       - AND lpd is started using 'lpd -L /path'
      - AND the /path file exists
     - AND the /path file has permissions allowing the user/group
    - the lpd runs as to open the file

    THEN: lpd will append error and trace messages to /path

    LPRng-3.6.1  -  LPRng-3.6.15  installed  LPD  setuid  ROOT.   This
    appears to be, as they say, a dumb move.

    The reason for the SETUID root installation appears to be a  typeo
    introduced in the LPRng-3.6.1 Makefile when Patrick was fixing  up
    the install code  to install the  lpr, lpc, lprm  and lpq programs
    optionally SETUID root  or as normal  processes.  It  appears that
    he installed the 'lpd'  program the same way.   This was in  spite
    of hos notes that "lpd should not be installed setuid ROOT".

    When the Linux SETUID problem was announced on June 8 he looked at
    LPRng and made sure that it did not have similar problems.  He did
    an  analysis  of  LPRng  and  discovered the SETUID install during
    testing.  He removed  the  SETUID install on the grounds that  one
    less possible compromise was  a good idea.   This was done in  the
    LPRng-3.6.16 released.

    The LPD  process is  usually started  up at  system initialization
    time.  But there is a simple attack that kills off a  surprisingly
    large number of servers.

    a) You start a large number of processes, each of which  allocates
       and modifies a large amounts  of memory.  See the  getrlimit(2)
       and limits(1) for the limits usually imposed on processes.  You
       can exhaust the swap area using this method on most systems.

    b) You now start  sending requests to the  server, i.e.- lpd.   If
       the lpd  process has  not allocated  enough memory  to hold the
       pending  requests  information,  then  it  will  do a malloc().
       This malloc() will  fail due to  brk(2) failing with:  [ENOMEM]
       Insufficient  space  existed  in  the  swap area to support the
       expansion, and this is a fatal error for the lpd process.

    Finally, lets look at  the files we can  modify.  The last  set of
    conditions mean that  the only files  that lpd can  modify are the
    ones owner  daemon/group daemon,  and that  have write permissions
    for user daemon/group daemon.   This, unfortunately, includes  the
    files in spool queues.

    So, if the user could find  a way to stop the running  lpd server,
    then they could append trace information into these files.

SOLUTION

    Remove SETUID permissions from 'lpd'

        chown root /usr/sbin/lpd
        chmod 555  /usr/sbin/lpd

    or

        chmod 500  /usr/sbin/lpd

    The current release (LPRng 3.6.20) installs it non-setuid.