[cups.bugs] [HIGH] STR #1996: broken error check in cups_write - can cause hang/crash

Simon Kelley simon at thekelleys.org.uk
Fri Sep 29 05:24:32 PDT 2006


[STR New]

I found this whilst trying to diagnose a cupsd which would go into a 100%
CPU hang after almost any activity. Running cupsd under strace showed an
endless series if write() system calls, each one returning -1 with ernno
as No Space Left on Device (that's an easy workaround). Each write call
has a buffer address one less then the previous one, and a requested size
one greater.

Pretty much all write calls in cups seem to be wrapped by cups_write() in
file.c, which, simplified, looks like this.

size_t        total, count
 
 total = 0;
  while (bytes > 0)
  {
      count = write(fp->fd, buf, bytes);

    if (count < 0)
    {
      if (errno == EAGAIN || errno == EINTR)
        continue;
      else
        return (-1);
    }
    bytes -= count;
    total += count;
    buf   += count;
  }

The problem is that count is declared as size_t, which is _unsigned_, so
the if (count < 0) test never succeeds, and when write returns -1 the code
loops forever, decrementing buf and incrementing total. Presumably buf
will eventually go out of bounds and the code will crash.

The fix is just to change the type of count and total to be ssize_t.

This bug exists in at least version2 1.2.2 (which I was using) and 1.3svn,
downloaded today.

Link: http://www.cups.org/str.php?L1996
Version: 1.3-current





More information about the cups-devel mailing list