Skip to content

Commit 102bb6e

Browse files
committed
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
1 parent 5e54fa7 commit 102bb6e

File tree

2 files changed

+9
-4
lines changed

2 files changed

+9
-4
lines changed

Diff for: src/appl/user_user/server.c

+3-1
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,10 @@ int main(argc, argv)
111111
}
112112
#endif
113113

114+
/* principal name must be sent null-terminated. */
114115
retval = krb5_read_message(context, (krb5_pointer) &sock, &pname_data);
115-
if (retval) {
116+
if (retval || pname_data.length == 0 ||
117+
pname_data.data[pname_data.length - 1] != '\0') {
116118
com_err ("uu-server", retval, "reading pname");
117119
return 2;
118120
}

Diff for: src/lib/krb5/krb/recvauth.c

+6-3
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ recvauth_common(krb5_context context,
5959
krb5_rcache rcache = 0;
6060
krb5_octet response;
6161
krb5_data null_server;
62+
krb5_data d;
6263
int need_error_free = 0;
6364
int local_rcache = 0, local_authcon = 0;
6465

@@ -77,7 +78,8 @@ recvauth_common(krb5_context context,
7778
*/
7879
if ((retval = krb5_read_message(context, fd, &inbuf)))
7980
return(retval);
80-
if (strcmp(inbuf.data, sendauth_version)) {
81+
d = make_data((char *)sendauth_version, strlen(sendauth_version) + 1);
82+
if (!data_eq(inbuf, d)) {
8183
problem = KRB5_SENDAUTH_BADAUTHVERS;
8284
response = 1;
8385
}
@@ -93,8 +95,9 @@ recvauth_common(krb5_context context,
9395
*/
9496
if ((retval = krb5_read_message(context, fd, &inbuf)))
9597
return(retval);
96-
if (appl_version && strcmp(inbuf.data, appl_version)) {
97-
if (!problem) {
98+
if (appl_version != NULL && !problem) {
99+
d = make_data(appl_version, strlen(appl_version) + 1);
100+
if (!data_eq(inbuf, d)) {
98101
problem = KRB5_SENDAUTH_BADAPPLVERS;
99102
response = 2;
100103
}

0 commit comments

Comments
 (0)