The Postfix SMTP server has a memory corruption error when the
Cyrus SASL library is used with authentication mechanisms other
than PLAIN and LOGIN (the ANONYMOUS mechanism is unaffected
but should not be enabled for different reasons). See below for
instructions to determine what systems are affected.

The error was introduced with the Postfix SASL patch, and is present
in all Postfix versions where the command "postconf mail_release_date"
reports a value of 20000314 (March 14, 2000) or greater.

This problem was discovered by Thomas Jarosch of Intra2net AG.

The memory corruption is known to result in a program crash
(SIGSEV). Remote code execution cannot be excluded. Such code would
execute as the unprivileged "postfix" user. This user has no control
over processes that run with non-postfix privileges including Postfix
processes running as root; the impact may be reduced with configurations
that enable the Postfix chroot feature or that use platform-dependent
privilege-reducing features.

The problem is fixed in Postfix stable releases 2.5.13, 2.6.10,
2.7.4, 2.8.3; in the Postfix 2.9 development release as of May 1,
2011; patches exist for Postfix version 1.1 and later. All this is
available from Postfix mirror sites listed at
http://www.postfix.org/download.html.

Disable Cyrus SASL authentication mechanisms for the Postfix SMTP
server other than PLAIN and LOGIN. The mechanisms are specified in
a Cyrus SASL smtpd.conf configuration file. This file may be found
in /etc/postfix/sasl/, /var/lib/sasl2/, /etc/sasl2/, /usr/lib/sasl2/
or /usr/local/lib/sasl2/.

In this file, update the "mech_list:" entry and remove any methods
other than PLAIN and LOGIN. For example, this configuration is not
affected:

mech_list: PLAIN LOGIN

Execute the command "postfix reload" to make the change effective,
then verify that the "port 25" and "port 587" services no longer
announce other SASL mechanisms, as shown in the previous section.

The Postfix SMTP server creates a SASL handle for each SMTP session,
when SASL authentication is enabled. The Postfix SMTP server will
use this SASL handle until it closes the SMTP connection (the Postfix
SMTP server may create a new server SASL handle when the client and
server agree to switch from a plaintext session to a TLS-encrypted
session, but this does not eliminate the memory corruption problem).

According to a comment in a Cyrus SASL include source file, a server
must not reuse a Cyrus SASL server handle after client authentication
failure. Instead, a server must create a new Cyrus SASL server
handle including mechanism list, before processing another client
authentication request.

The Postfix SMTP server fails to create a new Cyrus SASL server
handle after authentication failure. This causes memory corruption
when, for example, a client requests CRAM-MD5 authentication, fails
to authenticate, and then invokes some other authentication mechanism
except PLAIN (or ANONYMOUS if available). The likely outcome is that
the Postfix SMTP server process crashes with a segmentation violation
error (SIGSEGV, a.k.a. signal 11).

In the following example, S: indicates server output and C: indicates
client input. Line numbers are prepended for reference in the
background discussion in the next section.

When the SMTP client sends "*" to abort the CRAM-MD5 authentication
request (line 10 above), the CRAM-MD5 session context data structure
remains attached to the Cyrus SASL server handle. Postfix fails to
create a new Cyrus SASL server handle when the client sends the
subsequent "AUTH DIGEST-MD5" request (line 12 above); the DIGEST-MD5
method will therefore use the "wrong" session context data structure
(which was created after the "AUTH CRAM-MD5" request on line 8),
and will skip its "step 1" challenge.

Each Cyrus SASL authentication method has a different context data
structure layout. Because of these differences, the bits from the
CRAM-MD5 method's context data structure will not work as intended
with the DIGEST-MD5 method. As shown in the stack trace below, the
Postfix SMTP server process crashes in "step 2" of the DIGEST-MD5
authentication protocol. This happens while attempting to read from
a pointer that contains an invalid address.

In this particular example, the Postfix SMTP server crashes while
running under control of the GDB debugger (see the Postfix master(5)
manpage discussion of the -D option), while processing the SMTP
commands shown in the example above.

This stack trace was obtained after informing the GDB debugger of
SASL authentication methods that are linked in at runtime (example:
"add-symbol-file /usr/local/lib/sasl2/libdigestmd5.so.2 0x884b8e50").
Without that information, GDB reports a corrupted stack, because
it does not know that the program is executing legitimate code.

What context data structure bits does the DIGEST-MD5 method
inherit from the aborted CRAM-MD5 authentication request? As mentioned
earlier, different Cyrus SASL authentication methods have different
per-session context data structures. In particular, the CRAM-MD5
method uses a small structure while DIGEST-MD5 uses a larger one.

The DIGEST-MD5 method will therefore access memory outside the block
that was allocated during the aborted CRAM-MD5 request. That is,
it accesses random memory on the heap. The contents of that memory
will depend on the malloc implementation and on the program execution
history.

Version 2.1.23 of the Cyrus SASL library implements 12 authentication
methods. Of these, 9 methods maintain server session context data
structures that contain some mix of data and data pointers. When
these are read from random heap memory, or from a structure that
was allocated for a different SASL mechanism, all kinds of things
could happen. This is why remote code execution cannot be excluded.

There is no memory corruption problem with the "AUTH PLAIN" method,
because this does not use or create a dynamically-allocated session
context data structure. In particular, sending "AUTH LOGIN" after
aborting or failing an "AUTH PLAIN" request does not result in
memory corruption, because the PLAIN authentication method does not
allocate a session context data structure. Also, sending "AUTH
PLAIN" after aborting or failing an "AUTH LOGIN" request does not
result in memory corruption, because the PLAIN authentication method
ignores the per-session context data structure that is created by
the LOGIN authentication method. Finally, there is no memory
corruption when the LOGIN authentication method inherits a session
context data structure from an aborted or failed "AUTH LOGIN"
request.

It is for these reasons that Postfix SMTP servers with Cyrus SASL
support for only PLAIN and LOGIN are not affected. Fortunately,
PLAIN + LOGIN is the most commonly-used configuration, usually
combined with TLS encryption to protect passwords on the wire.
There will be a minor memory leak, but the Postfix SMTP server
limits the number of failed requests and thereby limits the leak.

There is no memory corruption problem with the "AUTH ANONYMOUS"
method, because just like "AUTH PLAIN" this does not create or use
a dynamically-allocated session context data structure. However,
"AUTH ANONYMOUS" support should not be enabled as it can make an
SMTP server an open relay.

April 18, 2011: After completing a detailed analysis of
what configurations are affected, and after testing solutions for
Postfix 1.1 .. 2.9, Wietse asked CERT/CC to notify vendors. Thank
you, CERT/CC.