summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--krb5-CVE-2007-5901.patch13
-rw-r--r--krb5-CVE-2007-5971.patch12
-rw-r--r--krb5-CVE-2008-0062,0063.patch339
-rw-r--r--krb5-CVE-2008-0947.patch75
-rw-r--r--krb5.spec21
5 files changed, 459 insertions, 1 deletions
diff --git a/krb5-CVE-2007-5901.patch b/krb5-CVE-2007-5901.patch
new file mode 100644
index 0000000..06b5b8f
--- /dev/null
+++ b/krb5-CVE-2007-5901.patch
@@ -0,0 +1,13 @@
+Patch for CVE-2007-5901, pulled from SVN per #415321.
+diff -up src/lib/gssapi/mechglue/g_initialize.c src/lib/gssapi/mechglue/g_initialize.c
+--- src/lib/gssapi/mechglue/g_initialize.c 2008-03-04 16:29:13.000000000 -0500
++++ src/lib/gssapi/mechglue/g_initialize.c 2008-03-04 16:29:16.000000000 -0500
+@@ -210,7 +210,7 @@ gss_OID_set *mechSet;
+ free((*mechSet)->elements[j].elements);
+ }
+ free((*mechSet)->elements);
+- free(mechSet);
++ free(*mechSet);
+ *mechSet = NULL;
+ return (GSS_S_FAILURE);
+ }
diff --git a/krb5-CVE-2007-5971.patch b/krb5-CVE-2007-5971.patch
new file mode 100644
index 0000000..234cf41
--- /dev/null
+++ b/krb5-CVE-2007-5971.patch
@@ -0,0 +1,12 @@
+Patch for CVE-2007-5971, pulled from SVN per #415351.
+diff -up src/lib/gssapi/krb5/k5sealv3.c src/lib/gssapi/krb5/k5sealv3.c
+--- src/lib/gssapi/krb5/k5sealv3.c 2008-03-04 16:22:29.000000000 -0500
++++ src/lib/gssapi/krb5/k5sealv3.c 2008-03-04 16:22:22.000000000 -0500
+@@ -248,7 +248,6 @@ gss_krb5int_make_seal_token_v3 (krb5_con
+ plain.data = 0;
+ if (err) {
+ zap(outbuf,bufsize);
+- free(outbuf);
+ goto error;
+ }
+ if (sum.length != ctx->cksum_size)
diff --git a/krb5-CVE-2008-0062,0063.patch b/krb5-CVE-2008-0062,0063.patch
new file mode 100644
index 0000000..aba0e4a
--- /dev/null
+++ b/krb5-CVE-2008-0062,0063.patch
@@ -0,0 +1,339 @@
+Patch from MITKRB5-SA-2008-001.
+Index: src/kdc/dispatch.c
+===================================================================
+--- src/kdc/dispatch.c (revision 20192)
++++ src/kdc/dispatch.c (working copy)
+@@ -1,7 +1,7 @@
+ /*
+ * kdc/dispatch.c
+ *
+- * Copyright 1990 by the Massachusetts Institute of Technology.
++ * Copyright 1990, 2007 by the Massachusetts Institute of Technology.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+@@ -107,7 +107,7 @@
+ retval = KRB5KRB_AP_ERR_MSG_TYPE;
+ #ifndef NOCACHE
+ /* put the response into the lookaside buffer */
+- if (!retval)
++ if (!retval && *response != NULL)
+ kdc_insert_lookaside(pkt, *response);
+ #endif
+
+Index: src/kdc/kerberos_v4.c
+===================================================================
+--- src/kdc/kerberos_v4.c (revision 20192)
++++ src/kdc/kerberos_v4.c (working copy)
+@@ -1,7 +1,7 @@
+ /*
+ * kdc/kerberos_v4.c
+ *
+- * Copyright 1985, 1986, 1987, 1988,1991 by the Massachusetts Institute
++ * Copyright 1985, 1986, 1987, 1988,1991,2007 by the Massachusetts Institute
+ * of Technology.
+ * All Rights Reserved.
+ *
+@@ -87,11 +87,6 @@
+ #define MSB_FIRST 0 /* 68000, IBM RT/PC */
+ #define LSB_FIRST 1 /* Vax, PC8086 */
+
+-int f;
+-
+-/* XXX several files in libkdb know about this */
+-char *progname;
+-
+ #ifndef BACKWARD_COMPAT
+ static Key_schedule master_key_schedule;
+ static C_Block master_key;
+@@ -143,10 +138,8 @@
+ #include "com_err.h"
+ #include "extern.h" /* to pick up master_princ */
+
+-static krb5_data *response;
+-
+-void kerberos_v4 (struct sockaddr_in *, KTEXT);
+-void kerb_err_reply (struct sockaddr_in *, KTEXT, long, char *);
++static krb5_data *kerberos_v4 (struct sockaddr_in *, KTEXT);
++static krb5_data *kerb_err_reply (struct sockaddr_in *, KTEXT, long, char *);
+ static int set_tgtkey (char *, krb5_kvno, krb5_boolean);
+
+ /* Attributes converted from V5 to V4 - internal representation */
+@@ -262,12 +255,12 @@
+ (void) klog(L_KRB_PERR, "V4 request too long.");
+ return KRB5KRB_ERR_FIELD_TOOLONG;
+ }
++ memset( &v4_pkt, 0, sizeof(v4_pkt));
+ v4_pkt.length = pkt->length;
+ v4_pkt.mbz = 0;
+ memcpy( v4_pkt.dat, pkt->data, pkt->length);
+
+- kerberos_v4( &client_sockaddr, &v4_pkt);
+- *resp = response;
++ *resp = kerberos_v4( &client_sockaddr, &v4_pkt);
+ return(retval);
+ }
+
+@@ -300,19 +293,20 @@
+ }
+
+ static
+-int krb4_sendto(int s, const char *msg, int len, int flags,
+- const struct sockaddr *to, int to_len)
++krb5_data *make_response(const char *msg, int len)
+ {
++ krb5_data *response;
++
+ if ( !(response = (krb5_data *) malloc( sizeof *response))) {
+- return ENOMEM;
++ return 0;
+ }
+ if ( !(response->data = (char *) malloc( len))) {
+ krb5_free_data(kdc_context, response);
+- return ENOMEM;
++ return 0;
+ }
+ response->length = len;
+ memcpy( response->data, msg, len);
+- return( 0);
++ return response;
+ }
+ static void
+ hang(void)
+@@ -586,7 +580,7 @@
+ *cp = 0;
+ }
+
+-void
++static krb5_data *
+ kerberos_v4(struct sockaddr_in *client, KTEXT pkt)
+ {
+ static KTEXT_ST rpkt_st;
+@@ -599,8 +593,8 @@
+ KTEXT auth = &auth_st;
+ AUTH_DAT ad_st;
+ AUTH_DAT *ad = &ad_st;
++ krb5_data *response = 0;
+
+-
+ static struct in_addr client_host;
+ static int msg_byte_order;
+ static int swap_bytes;
+@@ -637,8 +631,7 @@
+ inet_ntoa(client_host));
+ /* send an error reply */
+ req_name_ptr = req_inst_ptr = req_realm_ptr = "";
+- kerb_err_reply(client, pkt, KERB_ERR_PKT_VER, lt);
+- return;
++ return kerb_err_reply(client, pkt, KERB_ERR_PKT_VER, lt);
+ }
+
+ /* check packet version */
+@@ -648,8 +641,7 @@
+ KRB_PROT_VERSION, req_version, 0);
+ /* send an error reply */
+ req_name_ptr = req_inst_ptr = req_realm_ptr = "";
+- kerb_err_reply(client, pkt, KERB_ERR_PKT_VER, lt);
+- return;
++ return kerb_err_reply(client, pkt, KERB_ERR_PKT_VER, lt);
+ }
+ msg_byte_order = req_msg_type & 1;
+
+@@ -707,10 +699,10 @@
+
+ if ((i = check_princ(req_name_ptr, req_inst_ptr, 0,
+ &a_name_data, &k5key, 0, &ck5life))) {
+- kerb_err_reply(client, pkt, i, "check_princ failed");
++ response = kerb_err_reply(client, pkt, i, "check_princ failed");
+ a_name_data.key_low = a_name_data.key_high = 0;
+ krb5_free_keyblock_contents(kdc_context, &k5key);
+- return;
++ return response;
+ }
+ /* don't use k5key for client */
+ krb5_free_keyblock_contents(kdc_context, &k5key);
+@@ -722,11 +714,11 @@
+ /* this does all the checking */
+ if ((i = check_princ(service, instance, lifetime,
+ &s_name_data, &k5key, 1, &sk5life))) {
+- kerb_err_reply(client, pkt, i, "check_princ failed");
++ response = kerb_err_reply(client, pkt, i, "check_princ failed");
+ a_name_data.key_high = a_name_data.key_low = 0;
+ s_name_data.key_high = s_name_data.key_low = 0;
+ krb5_free_keyblock_contents(kdc_context, &k5key);
+- return;
++ return response;
+ }
+ /* Bound requested lifetime with service and user */
+ v4req_end = krb_life_to_time(kerb_time.tv_sec, req_life);
+@@ -797,8 +789,7 @@
+ rpkt = create_auth_reply(req_name_ptr, req_inst_ptr,
+ req_realm_ptr, req_time_ws, 0, a_name_data.exp_date,
+ a_name_data.key_version, ciph);
+- krb4_sendto(f, (char *) rpkt->dat, rpkt->length, 0,
+- (struct sockaddr *) client, sizeof (struct sockaddr_in));
++ response = make_response((char *) rpkt->dat, rpkt->length);
+ memset(&a_name_data, 0, sizeof(a_name_data));
+ memset(&s_name_data, 0, sizeof(s_name_data));
+ break;
+@@ -824,9 +815,8 @@
+ lt = klog(L_KRB_PERR,
+ "APPL request with realm length too long from %s",
+ inet_ntoa(client_host));
+- kerb_err_reply(client, pkt, RD_AP_INCON,
+- "realm length too long");
+- return;
++ return kerb_err_reply(client, pkt, RD_AP_INCON,
++ "realm length too long");
+ }
+
+ auth->length += (int) *(pkt->dat + auth->length) +
+@@ -835,9 +825,8 @@
+ lt = klog(L_KRB_PERR,
+ "APPL request with funky tkt or req_id length from %s",
+ inet_ntoa(client_host));
+- kerb_err_reply(client, pkt, RD_AP_INCON,
+- "funky tkt or req_id length");
+- return;
++ return kerb_err_reply(client, pkt, RD_AP_INCON,
++ "funky tkt or req_id length");
+ }
+
+ memcpy(auth->dat, pkt->dat, auth->length);
+@@ -848,18 +837,16 @@
+ if ((!allow_v4_crossrealm)&&strcmp(tktrlm, local_realm) != 0) {
+ lt = klog(L_ERR_UNK,
+ "Cross realm ticket from %s denied by policy,", tktrlm);
+- kerb_err_reply(client, pkt,
+- KERB_ERR_PRINCIPAL_UNKNOWN, lt);
+- return;
++ return kerb_err_reply(client, pkt,
++ KERB_ERR_PRINCIPAL_UNKNOWN, lt);
+ }
+ if (set_tgtkey(tktrlm, kvno, 0)) {
+- lt = klog(L_ERR_UNK,
++ lt = klog(L_ERR_UNK,
+ "FAILED set_tgtkey realm %s, kvno %d. Host: %s ",
+ tktrlm, kvno, inet_ntoa(client_host));
+ /* no better error code */
+- kerb_err_reply(client, pkt,
+- KERB_ERR_PRINCIPAL_UNKNOWN, lt);
+- return;
++ return kerb_err_reply(client, pkt,
++ KERB_ERR_PRINCIPAL_UNKNOWN, lt);
+ }
+ kerno = krb_rd_req(auth, "krbtgt", tktrlm, client_host.s_addr,
+ ad, 0);
+@@ -869,9 +856,8 @@
+ "FAILED 3des set_tgtkey realm %s, kvno %d. Host: %s ",
+ tktrlm, kvno, inet_ntoa(client_host));
+ /* no better error code */
+- kerb_err_reply(client, pkt,
+- KERB_ERR_PRINCIPAL_UNKNOWN, lt);
+- return;
++ return kerb_err_reply(client, pkt,
++ KERB_ERR_PRINCIPAL_UNKNOWN, lt);
+ }
+ kerno = krb_rd_req(auth, "krbtgt", tktrlm, client_host.s_addr,
+ ad, 0);
+@@ -881,8 +867,7 @@
+ klog(L_ERR_UNK, "FAILED krb_rd_req from %s: %s",
+ inet_ntoa(client_host), krb_get_err_text(kerno));
+ req_name_ptr = req_inst_ptr = req_realm_ptr = "";
+- kerb_err_reply(client, pkt, kerno, "krb_rd_req failed");
+- return;
++ return kerb_err_reply(client, pkt, kerno, "krb_rd_req failed");
+ }
+ ptr = (char *) pkt->dat + auth->length;
+
+@@ -904,22 +889,21 @@
+ req_realm_ptr = ad->prealm;
+
+ if (strcmp(ad->prealm, tktrlm)) {
+- kerb_err_reply(client, pkt, KERB_ERR_PRINCIPAL_UNKNOWN,
+- "Can't hop realms");
+- return;
++ return kerb_err_reply(client, pkt, KERB_ERR_PRINCIPAL_UNKNOWN,
++ "Can't hop realms");
+ }
+ if (!strcmp(service, "changepw")) {
+- kerb_err_reply(client, pkt, KERB_ERR_PRINCIPAL_UNKNOWN,
+- "Can't authorize password changed based on TGT");
+- return;
++ return kerb_err_reply(client, pkt, KERB_ERR_PRINCIPAL_UNKNOWN,
++ "Can't authorize password changed based on TGT");
+ }
+ kerno = check_princ(service, instance, req_life,
+ &s_name_data, &k5key, 1, &sk5life);
+ if (kerno) {
+- kerb_err_reply(client, pkt, kerno, "check_princ failed");
++ response = kerb_err_reply(client, pkt, kerno,
++ "check_princ failed");
+ s_name_data.key_high = s_name_data.key_low = 0;
+ krb5_free_keyblock_contents(kdc_context, &k5key);
+- return;
++ return response;
+ }
+ /* Bound requested lifetime with service and user */
+ v4endtime = krb_life_to_time((KRB4_32)ad->time_sec, ad->life);
+@@ -975,8 +959,7 @@
+ rpkt = create_auth_reply(ad->pname, ad->pinst,
+ ad->prealm, time_ws,
+ 0, 0, 0, ciph);
+- krb4_sendto(f, (char *) rpkt->dat, rpkt->length, 0,
+- (struct sockaddr *) client, sizeof (struct sockaddr_in));
++ response = make_response((char *) rpkt->dat, rpkt->length);
+ memset(&s_name_data, 0, sizeof(s_name_data));
+ break;
+ }
+@@ -1001,6 +984,7 @@
+ break;
+ }
+ }
++ return response;
+ }
+
+
+@@ -1010,7 +994,7 @@
+ * client.
+ */
+
+-void
++static krb5_data *
+ kerb_err_reply(struct sockaddr_in *client, KTEXT pkt, long int err, char *string)
+ {
+ static KTEXT_ST e_pkt_st;
+@@ -1021,9 +1005,7 @@
+ strncat(e_msg, string, sizeof(e_msg) - 1 - 19);
+ cr_err_reply(e_pkt, req_name_ptr, req_inst_ptr, req_realm_ptr,
+ req_time_ws, err, e_msg);
+- krb4_sendto(f, (char *) e_pkt->dat, e_pkt->length, 0,
+- (struct sockaddr *) client, sizeof (struct sockaddr_in));
+-
++ return make_response((char *) e_pkt->dat, e_pkt->length);
+ }
+
+ static int
+Index: src/kdc/network.c
+===================================================================
+--- src/kdc/network.c (revision 20192)
++++ src/kdc/network.c (working copy)
+@@ -1,7 +1,7 @@
+ /*
+ * kdc/network.c
+ *
+- * Copyright 1990,2000 by the Massachusetts Institute of Technology.
++ * Copyright 1990,2000,2007 by the Massachusetts Institute of Technology.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+@@ -747,6 +747,8 @@
+ com_err(prog, retval, "while dispatching (udp)");
+ return;
+ }
++ if (response == NULL)
++ return;
+ cc = sendto(port_fd, response->data, (socklen_t) response->length, 0,
+ (struct sockaddr *)&saddr, saddr_len);
+ if (cc == -1) {
+
diff --git a/krb5-CVE-2008-0947.patch b/krb5-CVE-2008-0947.patch
new file mode 100644
index 0000000..0a0183c
--- /dev/null
+++ b/krb5-CVE-2008-0947.patch
@@ -0,0 +1,75 @@
+Patch from MITKRB5-SA-2008-002.
+=== src/lib/rpc/svc.c
+==================================================================
+--- src/lib/rpc/svc.c (revision 1666)
++++ src/lib/rpc/svc.c (local)
+@@ -109,15 +109,17 @@
+ if (sock < FD_SETSIZE) {
+ xports[sock] = xprt;
+ FD_SET(sock, &svc_fdset);
++ if (sock > svc_maxfd)
++ svc_maxfd = sock;
+ }
+ #else
+ if (sock < NOFILE) {
+ xports[sock] = xprt;
+ svc_fds |= (1 << sock);
++ if (sock > svc_maxfd)
++ svc_maxfd = sock;
+ }
+ #endif /* def FD_SETSIZE */
+- if (sock > svc_maxfd)
+- svc_maxfd = sock;
+ }
+
+ /*
+=== src/lib/rpc/svc_tcp.c
+==================================================================
+--- src/lib/rpc/svc_tcp.c (revision 1666)
++++ src/lib/rpc/svc_tcp.c (local)
+@@ -54,6 +54,14 @@
+ extern errno;
+ */
+
++#ifndef FD_SETSIZE
++#ifdef NBBY
++#define NOFILE (sizeof(int) * NBBY)
++#else
++#define NOFILE (sizeof(int) * 8)
++#endif
++#endif
++
+ /*
+ * Ops vector for TCP/IP based rpc service handle
+ */
+@@ -215,6 +223,19 @@
+ register SVCXPRT *xprt;
+ register struct tcp_conn *cd;
+
++#ifdef FD_SETSIZE
++ if (fd >= FD_SETSIZE) {
++ (void) fprintf(stderr, "svc_tcp: makefd_xprt: fd too high\n");
++ xprt = NULL;
++ goto done;
++ }
++#else
++ if (fd >= NOFILE) {
++ (void) fprintf(stderr, "svc_tcp: makefd_xprt: fd too high\n");
++ xprt = NULL;
++ goto done;
++ }
++#endif
+ xprt = (SVCXPRT *)mem_alloc(sizeof(SVCXPRT));
+ if (xprt == (SVCXPRT *)NULL) {
+ (void) fprintf(stderr, "svc_tcp: makefd_xprt: out of memory\n");
+@@ -271,6 +292,10 @@
+ * make a new transporter (re-uses xprt)
+ */
+ xprt = makefd_xprt(sock, r->sendsize, r->recvsize);
++ if (xprt == NULL) {
++ close(sock);
++ return (FALSE);
++ }
+ xprt->xp_raddr = addr;
+ xprt->xp_addrlen = len;
+ xprt->xp_laddr = laddr;
diff --git a/krb5.spec b/krb5.spec
index 43dfe89..8179a24 100644
--- a/krb5.spec
+++ b/krb5.spec
@@ -16,7 +16,7 @@
Summary: The Kerberos network authentication system.
Name: krb5
Version: 1.6.3
-Release: 9%{?dist}
+Release: 10%{?dist}
# Maybe we should explode from the now-available-to-everybody tarball instead?
# http://web.mit.edu/kerberos/dist/krb5/1.6/krb5-1.6.2-signed.tar
Source0: krb5-%{version}.tar.gz
@@ -96,6 +96,10 @@ Patch70: krb5-trunk-kpasswd_tcp2.patch
Patch71: krb5-1.6.2-dirsrv-accountlock.patch
Patch72: krb5-1.6.3-ftp_fdleak.patch
Patch73: krb5-1.6.3-ftp_glob_runique.patch
+Patch74: krb5-CVE-2008-0062,0063.patch
+Patch75: krb5-CVE-2008-0947.patch
+Patch76: krb5-CVE-2007-5901.patch
+Patch77: krb5-CVE-2007-5971.patch
License: MIT, freely distributable.
URL: http://web.mit.edu/kerberos/www/
@@ -226,6 +230,17 @@ to obtain initial credentials from a KDC using a private key and a
certificate.
%changelog
+* Tue Mar 18 2008 Nalin Dahyabhai <nalin@redhat.com> 1.6.3-10
+- add fixes from MITKRB5-SA-2008-001 for use of null or dangling pointer
+ when v4 compatibility is enabled on the KDC (CVE-2008-0062, CVE-2008-0063,
+ #432620, #432621)
+- add fixes from MITKRB5-SA-2008-002 for array out-of-bounds accesses when
+ high-numbered descriptors are used (CVE-2008-0947, #433596)
+- add backport bug fix for an attempt to free non-heap memory in
+ libgssapi_krb5 (CVE-2007-5901, #415321)
+- add backport bug fix for a double-free in out-of-memory situations in
+ libgssapi_krb5 (CVE-2007-5971, #415351)
+
* Tue Mar 18 2008 Nalin Dahyabhai <nalin@redhat.com> 1.6.3-9
- rework file labeling patch to not depend on fragile preprocessor trickery,
in another attempt at fixing #428355 and friends
@@ -1330,6 +1345,10 @@ popd
%patch71 -p1 -b .dirsrv-accountlock
%patch72 -p1 -b .ftp_fdleak
%patch73 -p1 -b .ftp_glob_runique
+%patch74 -p0 -b .2008-0062,0063
+%patch75 -p0 -b .2008-0947
+%patch76 -p0 -b .2007-5901
+%patch77 -p0 -b .2007-5971
cp src/krb524/README README.krb524
gzip doc/*.ps