fetchmail-friends
[Top] [All Lists]

[fetchmail] [Marius Gedminas <mgedmin(_at_)delfi(_dot_)lt>] Bug#176938: fetchmail: garbage in error messages due to unsafe use of snprintf

2003-02-12 08:08:22

Hi friends,

here is another report from a Debian user (bug #176938).  It is about
a buffer overflow.  It includes a possible fix.

[ Note: thinking of security issues, I tried to contact Eric directly
  about this bug, but got no answer.  Looking more deeply at the
  problem, security risks are not that high not to forward this to
  friends. ]

Cheers,
Benjamin

--- Begin Message ---
Package: fetchmail
Version: 6.2.0-2
Severity: normal

Twice within the last couple of months I got a message from fetchmail
that looks like this:

  Fetchmail could not get mail from username(_at_)pop3server(_dot_)

  The attempt to get authorization failed.
  Since we have already succeeded in getting authorization for this
  connection, this is probably another failure mode (such as busy server)
  that fetchmail cannot distinguish because the server didn't send a useful
  error message.

  However, if you HAVE changed your account details since starting the
  fetchmail daemon, you need to stop the daemon, change your configuration
  of fetchmail, and then restart the daemon.

  The fetchmail daemon will continue running and attempt
  
+t^@(\375\377\277j^?^E^HHl^H^H\300^F^G^H\300^F^G^H\350\212^H^HHl^H^H(_at_)^F^G^H^Pl^H^H\350\212^H^H^@^(_at_)^@^(_at_)2^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@\234\334
  
\377\277^(_at_)^@^(_at_)^@\3404^E^H\3404^E^H^(_at_)^@^(_at_)^@\377\377\377\377\377\377\377\377^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@
  
+^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^@
  
+^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^@
  
+^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^(_at_)^@^@

(the + signs are due to Mutt's line wrapping, same applies to ^@ and \nnn).

Basically the problem is stuff_warning (sink.c:1478):

    char        buf[POPBUFSIZE];
...
    vsnprintf(buf, sizeof(buf), fmt, ap);
...
    snprintf(buf+strlen(buf), sizeof(buf)-strlen(buf), "\r\n");
...
    stuffline(ctl, buf);

Stuffline expects buf to be terminated by \n\0, but obviously buf is not
guaranteed to have even a terminating \0, due to idiosyncracies of snprintf.
Thus random memory contents are displayed (e.g. I see a command used to
initiate an ssh tunnel for a different account, some IMAP messages; haven't
noticed any passwords yet)

The actual call which passes a string longer than 512 characters is in
do_session (driver.c, line 1124).

Note that the texts are i18nized, thus you cannot rely on them being shorter
than a given number of characters.

Suggested fix: increase stuff_warning buffer size (to avoid truncation of
fetchmail error messages), fix all calls to snprintf/vsnprintf to manually
ensure strings are terminated properly.  Maybe grep for occurrences of
strncpy/strncat as well.

I admit that I had a higher opinion on fetchmail before I glanced at the
#ifdef-packed source code.  I cannot say that I like bits like

  #ifdef HAVE_SNPRINTF
      snprintf(buf+strlen(buf), sizeof(buf)-strlen(buf), "\r\n");
  #else
      strcat(buf, "\r\n");
  #endif /* HAVE_SNPRINTF */

If the platform is broken and doesn't have snprintf (BTW why not use strncat
here?), why isn't there a probably slower portable C implementation included
with fetchmail, instead of leaving a buffer-overflow waiting to happen?

-- System Information:
Debian Release: testing/unstable
Architecture: i386
Kernel: Linux mg 2.4.19-mg #2 Fri Nov 1 16:36:59 EET 2002 i686
Locale: LANG=C, LC_CTYPE=lt_LT.UTF-8

Versions of packages fetchmail depends on:
ii  adduser                       3.49       Add and remove users and groups
ii  base-files                    3.0.6      Debian base system miscellaneous f
ii  debconf                       1.2.21     Debian configuration management sy
ii  debianutils                   2.1.2      Miscellaneous utilities specific t
ii  libc6                         2.3.1-9    GNU C Library: Shared libraries an
ii  libssl0.9.6                   0.9.6g-10  SSL shared libraries

-- debconf information:
* fetchmail/confwarn: 
* fetchmail/systemwide: false
* fetchmail/initdefaultswarn: 
  fetchmail/runasroot: false
  fetchmail/fetchidswarn: 


Marius Gedminas
-- 
Colorless green ideas sleep furiously.




--- End Message ---
<Prev in Thread] Current Thread [Next in Thread>