Commit message: Fix krb5_read_message handling [CVE-2014-5355]

In recvauth_common, do not use strcmp against the data fields of
krb5_data objects populated by krb5_read_message(), as there is no
guarantee that they are C strings.  Instead, create an expected
krb5_data value and use data_eq().

In the sample user-to-user server application, check that the received
client principal name is null-terminated before using it with printf
and krb5_parse_name.

CVE-2014-5355:

In MIT krb5, when a server process uses the krb5_recvauth function, an
unauthenticated remote attacker can cause a NULL dereference by
sending a zero-byte version string, or a read beyond the end of
allocated storage by sending a non-null-terminated version string.
The example user-to-user server application (uuserver) is similarly
vulnerable to a zero-length or non-null-terminated principal name
string.

The krb5_recvauth function reads two version strings from the client
using krb5_read_message(), which produces a krb5_data structure
containing a length and a pointer to an octet sequence.  krb5_recvauth
assumes that the data pointer is a valid C string and passes it to
strcmp() to verify the versions.  If the client sends an empty octet
sequence, the data pointer will be NULL and strcmp() will dereference
a NULL pointer, causing the process to crash.  If the client sends a
non-null-terminated octet sequence, strcmp() will read beyond the end
of the allocated storage, possibly causing the process to crash.

uuserver similarly uses krb5_read_message() to read a client principal
name, and then passes it to printf() and krb5_parse_name() without
verifying that it is a valid C string.

The krb5_recvauth function is used by kpropd and the Kerberized
versions of the BSD rlogin and rsh daemons.  These daemons are usually
run out of inetd or in a mode which forks before processing incoming
connections, so a process crash will generally not result in a
complete denial of service.

Thanks to Tim Uglow for discovering this issue.

CVSSv2: AV:N/AC:L/Au:N/C:N/I:N/A:P/E:POC/RL:OF/RC:C

[tlyu@mit.edu: CVSS score]

ticket: 8050 (new)
target_version: 1.13.1
tags: pullup
CVE: CVE-2014-5355
CWE: CWE-703
Vulnerability description: MIT Kerberos 5 (aka krb5) through 1.13.1 incorrectly expects that a krb5_read_message data field is represented as a string ending with a '\0' character, which allows remote attackers to (1) cause a denial of service (NULL pointer dereference) via a zero-byte version string or (2) cause a denial of service (out-of-bounds read) by omitting the '\0' character, related to appl/user_user/server.c and lib/krb5/krb/recvauth.c.

Project: krb5
File: recvauth.c

krb5_recvauth(krb5_context context, krb5_auth_context *auth_context, krb5_pointer fd, char *appl_version, krb5_principal server, krb5_int32 flags, krb5_keytab keytab, krb5_ticket **ticket)
{
    return recvauth_common (context, auth_context, fd, appl_version,
                            server, flags, keytab, ticket, 0);
}

Project: krb5
File: recvauth.c

krb5_recvauth_version(krb5_context context,
                      krb5_auth_context *auth_context,
                      /* IN */
                      krb5_pointer fd,
                      krb5_principal server,
                      krb5_int32 flags,
                      krb5_keytab keytab,
                      /* OUT */
                      krb5_ticket **ticket,
                      krb5_data *version)
{
    return recvauth_common (context, auth_context, fd, 0,
                            server, flags, keytab, ticket, version);
}