git: 6bc209f5dd - main - Add SA-22:14.

From: Gordon Tetlow <gordon_at_FreeBSD.org>
Date: Wed, 16 Nov 2022 03:01:51 UTC
The branch main has been updated by gordon (src committer):

URL: https://cgit.FreeBSD.org/doc/commit/?id=6bc209f5dd7eb30a0e655c75e884a3e0fe7ce10a

commit 6bc209f5dd7eb30a0e655c75e884a3e0fe7ce10a
Author:     Gordon Tetlow <gordon@FreeBSD.org>
AuthorDate: 2022-11-16 03:00:48 +0000
Commit:     Gordon Tetlow <gordon@FreeBSD.org>
CommitDate: 2022-11-16 03:00:48 +0000

    Add SA-22:14.
    
    Approved by:    so
---
 website/data/security/advisories.toml              |    4 +
 .../advisories/FreeBSD-SA-22:14.heimdal.asc        |  173 +++
 .../static/security/patches/SA-22:14/heimdal.patch | 1400 ++++++++++++++++++++
 .../security/patches/SA-22:14/heimdal.patch.asc    |   16 +
 4 files changed, 1593 insertions(+)

diff --git a/website/data/security/advisories.toml b/website/data/security/advisories.toml
index a5aadbdf0d..9f761f4ff7 100644
--- a/website/data/security/advisories.toml
+++ b/website/data/security/advisories.toml
@@ -1,6 +1,10 @@
 # Sort advisories by year, month and day
 # $FreeBSD$
 
+[[advisories]]
+name = "FreeBSD-SA-22:14.heimdal"
+date = "2022-11-15"
+
 [[advisories]]
 name = "FreeBSD-SA-22:13.zlib"
 date = "2022-08-30"
diff --git a/website/static/security/advisories/FreeBSD-SA-22:14.heimdal.asc b/website/static/security/advisories/FreeBSD-SA-22:14.heimdal.asc
new file mode 100644
index 0000000000..93947ecf2c
--- /dev/null
+++ b/website/static/security/advisories/FreeBSD-SA-22:14.heimdal.asc
@@ -0,0 +1,173 @@
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA512
+
+=============================================================================
+FreeBSD-SA-22:14.heimdal                                    Security Advisory
+                                                          The FreeBSD Project
+
+Topic:          Multiple vulnerabilities in Heimdal
+
+Category:       contrib
+Module:         heimdal
+Announced:      2022-11-15
+Affects:        All supported versions of FreeBSD.
+Corrected:      2022-11-15 21:15:35 UTC (stable/13, 13.1-STABLE)
+                2022-11-16 01:50:27 UTC (releng/13.1, 13.1-RELEASE-p4)
+                2022-11-15 21:16:56 UTC (stable/12, 12.4-STABLE)
+                2022-11-16 01:47:57 UTC (releng/12.4, 12.4-RC2-p1)
+                2022-11-16 01:40:21 UTC (releng/12.3, 12.3-RELEASE-p9)
+CVE Name:       CVE-2019-14870, CVE-2022-3437, CVE-2022-42898,
+                CVE-2022-44640, CVE-2021-44758
+
+For general information regarding FreeBSD Security Advisories,
+including descriptions of the fields above, security branches, and the
+following sections, please visit <URL:https://security.FreeBSD.org/>.
+
+I.   Background
+
+Heimdal implements the Kerberos 5 network authentication protocols.
+
+A Key Distribution Center (KDC) is trusted by all principals registered
+in that administrative "realm" to store a secret key in confidence, of
+which, the proof of knowledge is used to verify the authenticity of a
+principal.
+
+II.  Problem Description
+
+Multiple security vulnerabilities have been discovered in the Heimdal
+implementation of the Kerberos 5 network authentication protocols and KDC.
+
+- - CVE-2022-42898 PAC parse integer overflows
+- - CVE-2022-3437 Overflows and non-constant time leaks in DES{,3} and arcfour
+- - CVE-2021-44758 NULL dereference DoS in SPNEGO acceptors
+- - CVE-2022-44640 Heimdal KDC: invalid free in ASN.1 codec
+- - CVE-2019-14870 Validate client attributes in protocol-transition
+- - CVE-2019-14870 Apply forwardable policy in protocol-transition
+- - CVE-2019-14870 Always lookup impersonate client in DB
+
+III. Impact
+
+A malicious actor with control of the network between a client and a service
+using Kerberos for authentication can impersonate either the client or the
+service, enabling a man-in-the-middle (MITM) attack circumventing mutual
+authentication.
+
+Note that, while CVE-2022-44640 is a severe vulnerability, possibly enabling
+remote code execution on other platforms, the version of Heimdal included with
+the FreeBSD base system cannot be exploited in this way on FreeBSD.
+
+IV.  Workaround
+
+No workaround is available, but only systems using Kerberos are affected.
+
+V.   Solution
+
+Upgrade your vulnerable system to a supported FreeBSD stable or
+release / security branch (releng) dated after the correction date.
+
+A reboot is recommended.
+
+Perform one of the following:
+
+1) To update your vulnerable system via a binary patch:
+
+Systems running a RELEASE version of FreeBSD on the amd64, i386, or
+(on FreeBSD 13 and later) arm64 platforms can be updated via the
+freebsd-update(8) utility:
+
+# freebsd-update fetch
+# freebsd-update install
+
+A reboot is recommended.
+
+2) To update your vulnerable system via a source code patch:
+
+The following patches have been verified to apply to the applicable
+FreeBSD release branches.
+
+a) Download the relevant patch from the location below, and verify the
+detached PGP signature using your PGP utility.
+
+# fetch https://security.FreeBSD.org/patches/SA-22:14/heimdal.patch
+# fetch https://security.FreeBSD.org/patches/SA-22:14/heimdal.patch.asc
+# gpg --verify heimdal.patch.asc
+
+b) Apply the patch.  Execute the following commands as root:
+
+# cd /usr/src
+# patch < /path/to/patch
+
+c) Recompile the operating system using buildworld and installworld as
+described in <URL:https://www.FreeBSD.org/handbook/makeworld.html>.
+
+Restart all daemons that use the Kerberos, or reboot the system.
+
+VI.  Correction details
+
+This issue is corrected by the corresponding Git commit hash or Subversion
+revision number in the following stable and release branches:
+
+Branch/path                             Hash                     Revision
+- -------------------------------------------------------------------------
+stable/13/                              d0b6550173d2    stable/13-n253097
+releng/13.1/                            a1e014e89282  releng/13.1-n250170
+stable/12/                                                        r372752
+releng/12.4/                                                      r372755
+releng/12.3/                                                      r372753
+- -------------------------------------------------------------------------
+
+For FreeBSD 13 and later:
+
+Run the following command to see which files were modified by a
+particular commit:
+
+# git show --stat <commit hash>
+
+Or visit the following URL, replacing NNNNNN with the hash:
+
+<URL:https://cgit.freebsd.org/src/commit/?id=NNNNNN>
+
+To determine the commit count in a working tree (for comparison against
+nNNNNNN in the table above), run:
+
+# git rev-list --count --first-parent HEAD
+
+For FreeBSD 12 and earlier:
+
+Run the following command to see which files were modified by a particular
+revision, replacing NNNNNN with the revision number:
+
+# svn diff -cNNNNNN --summarize svn://svn.freebsd.org/base
+
+Or visit the following URL, replacing NNNNNN with the revision number:
+
+<URL:https://svnweb.freebsd.org/base?view=revision&revision=NNNNNN>
+
+VII. References
+
+<URL:https://github.com/heimdal/heimdal/releases/tag/heimdal-7.8.0>
+
+<URL:https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-14870>
+<URL:https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-44758>
+<URL:https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-3437>
+<URL:https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-42898>
+<URL:https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-44640>
+
+The latest revision of this advisory is available at
+<URL:https://security.FreeBSD.org/advisories/FreeBSD-SA-22:14.heimdal.asc>
+-----BEGIN PGP SIGNATURE-----
+
+iQIzBAEBCgAdFiEE/A6HiuWv54gCjWNV05eS9J6n5cIFAmN0Ud0ACgkQ05eS9J6n
+5cKIKA//bRccdsoilKJvyQw9RazwJ0HENGbPF1RdjyG1nmMsp5wG+rqAdnN0LF8p
+SgEqfZjCx+KXNJBkzblKzduFK9VQ211dbjouwd/BVCbMYemUIs1DqobF6uvYnMbn
+vhQ2lUtZ46WbgvjXOcfsHakmCV2V2kCzBFsCKCQFPcYSch5n9gGW+I4cfewF8+fB
++sjvhz7MDyLaCVB3UpxPUIMc3w/G18zzyhHdhuJOaCrCjf00Mt4Er40ICr+IkRy5
+PpwdX60yvwk3uxzzMyIC5zcS3CD6qFUOaSIXfEuGWGl7Wo7MjoCXECE1sbwLVat8
+K1FJtNIADZJkURzkgjvp9rHQHwZFkLMawrkyik4apHgGsY2pXktZGhcw/qN2BNNn
+uo3HILrjbYK5eU5zLU17FS9X5qTurIcqdVJCIklvjNqW7DAuN3K1I9ryat4w5sST
+ToW5LpLtP9DoI9M9Bh3Mqba629iuXRmQ6LZ6p9EGSFr2i7e3VDEcvMxkGO6Sh8M3
+w67FpqWzeQ1RT2q2YL013emKq6C+oYDjMDDejAqH2Wwwae/7yQiNnXBqvokIXmi4
+KLupHptt0CPFPOFBLloxXBPenYu/49SRWeUoxBqspQuvCY708j1mUntaVtAFm/ax
+QElUUEEmcuJhsBzTzBnS82oe7IRwv3NQm55zkOn+DQZ2HjV/GaY=
+=jmOK
+-----END PGP SIGNATURE-----
diff --git a/website/static/security/patches/SA-22:14/heimdal.patch b/website/static/security/patches/SA-22:14/heimdal.patch
new file mode 100644
index 0000000000..df1be0e924
--- /dev/null
+++ b/website/static/security/patches/SA-22:14/heimdal.patch
@@ -0,0 +1,1400 @@
+--- crypto/heimdal/admin/change.c.orig
++++ crypto/heimdal/admin/change.c
+@@ -217,7 +217,6 @@
+     krb5_kt_end_seq_get(context, keytab, &cursor);
+ 
+     if (ret == KRB5_KT_END) {
+-	ret = 0;
+ 	for (i = 0; i < j; i++) {
+ 	    if (verbose_flag) {
+ 		char *client_name;
+--- crypto/heimdal/appl/gssmask/gssmask.c.orig
++++ crypto/heimdal/appl/gssmask/gssmask.c
+@@ -949,7 +949,9 @@
+     memcpy(p, iov[4].buffer.value, iov[4].buffer.length);
+     p += iov[4].buffer.length;
+     memcpy(p, iov[5].buffer.value, iov[5].buffer.length);
++#ifndef __clang_analyzer__
+     p += iov[5].buffer.length;
++#endif
+ 
+     gss_release_iov_buffer(NULL, iov, iov_len);
+ 
+--- crypto/heimdal/kadmin/kadmind.c.orig
++++ crypto/heimdal/kadmin/kadmind.c
+@@ -116,7 +116,11 @@
+     }
+ 
+     argc -= optidx;
++#ifndef __clang_analyzer__
+     argv += optidx;
++#endif
++    if (argc != 0)
++        usage(1);
+ 
+     if (config_file == NULL) {
+ 	asprintf(&config_file, "%s/kdc.conf", hdb_db_dir(context));
+--- crypto/heimdal/kadmin/mod.c.orig
++++ crypto/heimdal/kadmin/mod.c
+@@ -106,7 +106,7 @@
+ add_aliases(krb5_context contextp, kadm5_principal_ent_rec *princ,
+ 	    struct getarg_strings *strings)
+ {
+-    krb5_error_code ret;
++    krb5_error_code ret = 0;
+     HDB_extension ext;
+     krb5_data buf;
+     krb5_principal p;
+@@ -127,9 +127,16 @@
+ 		   sizeof(ext.data.u.aliases.aliases.val[0]));
+ 	ext.data.u.aliases.aliases.len = strings->num_strings;
+ 
+-	for (i = 0; i < strings->num_strings; i++) {
++	for (i = 0; ret == 0 && i < strings->num_strings; i++) {
+ 	    ret = krb5_parse_name(contextp, strings->strings[i], &p);
+-	    ret = copy_Principal(p, &ext.data.u.aliases.aliases.val[i]);
++            if (ret)
++                krb5_err(contextp, 1, ret, "Could not parse alias %s",
++                         strings->strings[i]);
++            if (ret == 0)
++                ret = copy_Principal(p, &ext.data.u.aliases.aliases.val[i]);
++            if (ret)
++                krb5_err(contextp, 1, ret, "Could not copy parsed alias %s",
++                         strings->strings[i]);
+ 	    krb5_free_principal(contextp, p);
+ 	}
+     }
+--- crypto/heimdal/kadmin/stash.c.orig
++++ crypto/heimdal/kadmin/stash.c
+@@ -103,7 +103,10 @@
+ 	    }
+ 	}
+ 	ret = krb5_string_to_key_salt(context, enctype, buf, salt, &key);
+-	ret = hdb_add_master_key(context, &key, &mkey);
++        if (ret == 0)
++            ret = hdb_add_master_key(context, &key, &mkey);
++        if (ret)
++            krb5_warn(context, errno, "setting master key");
+ 	krb5_free_keyblock_contents(context, &key);
+     }
+ 
+--- crypto/heimdal/kcm/protocol.c.orig
++++ crypto/heimdal/kcm/protocol.c
+@@ -423,7 +423,7 @@
+     free(name);
+     kcm_release_ccache(context, ccache);
+ 
+-    return 0;
++    return ret;
+ }
+ 
+ /*
+--- crypto/heimdal/kdc/digest.c.orig
++++ crypto/heimdal/kdc/digest.c
+@@ -1467,6 +1467,10 @@
+     ret = krb5_encrypt_EncryptedData(context, crypto, KRB5_KU_DIGEST_ENCRYPT,
+ 				     buf.data, buf.length, 0,
+ 				     &rep.innerRep);
++    if (ret) {
++        krb5_prepend_error_message(context, ret, "Failed to encrypt digest: ");
++        goto out;
++    }
+ 
+     ASN1_MALLOC_ENCODE(DigestREP, reply->data, reply->length, &rep, &size, ret);
+     if (ret) {
+--- crypto/heimdal/kdc/hpropd.c.orig
++++ crypto/heimdal/kdc/hpropd.c
+@@ -107,7 +107,9 @@
+     }
+ 
+     argc -= optidx;
++#ifndef __clang_analyzer__
+     argv += optidx;
++#endif
+ 
+     if (argc != 0)
+ 	usage(1);
+@@ -125,6 +127,7 @@
+ 	krb5_ticket *ticket;
+ 	char *server;
+ 
++        memset(&ss, 0, sizeof(ss));
+ 	sock = STDIN_FILENO;
+ #ifdef SUPPORT_INETD
+ 	if (inetd_flag == -1) {
+--- crypto/heimdal/kdc/kdc-replay.c.orig
++++ crypto/heimdal/kdc/kdc-replay.c
+@@ -184,6 +184,8 @@
+ 	    unsigned int tag2;
+ 	    ret = der_get_tag (r.data, r.length,
+ 			       &cl, &ty, &tag2, NULL);
++            if (ret)
++                krb5_err(context, 1, ret, "Could not decode replay data");
+ 	    if (MAKE_TAG(cl, ty, 0) != clty)
+ 		krb5_errx(context, 1, "class|type mismatch: %d != %d",
+ 			  (int)MAKE_TAG(cl, ty, 0), (int)clty);
+--- crypto/heimdal/kdc/krb5tgs.c.orig
++++ crypto/heimdal/kdc/krb5tgs.c
+@@ -1928,30 +1928,40 @@
+ 	    if (ret)
+ 		goto out;
+ 
++	    ret = _kdc_db_fetch(context, config, tp, HDB_F_GET_CLIENT | flags,
++				NULL, &s4u2self_impersonated_clientdb,
++				&s4u2self_impersonated_client);
++	    if (ret) {
++		const char *msg;
++
++		/*
++		 * If the client belongs to the same realm as our krbtgt, it
++		 * should exist in the local database.
++		 *
++		 */
++
++		if (ret == HDB_ERR_NOENTRY)
++		    ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN;
++		msg = krb5_get_error_message(context, ret);
++		kdc_log(context, config, 2,
++			"S4U2Self principal to impersonate %s not found in database: %s",
++			tpn, msg);
++		krb5_free_error_message(context, msg);
++		goto out;
++	    }
++
++	    free(s4u2self_impersonated_client->entry.pw_end);
++	    s4u2self_impersonated_client->entry.pw_end = NULL;
++
++	    ret = kdc_check_flags(context, config, s4u2self_impersonated_client, tpn,
++				  NULL, NULL, FALSE);
++	    if (ret)
++		goto out;
++
+ 	    /* If we were about to put a PAC into the ticket, we better fix it to be the right PAC */
+ 	    if(rspac.data) {
+ 		krb5_pac p = NULL;
+ 		krb5_data_free(&rspac);
+-		ret = _kdc_db_fetch(context, config, tp, HDB_F_GET_CLIENT | flags,
+-				    NULL, &s4u2self_impersonated_clientdb, &s4u2self_impersonated_client);
+-		if (ret) {
+-		    const char *msg;
+-
+-		    /*
+-		     * If the client belongs to the same realm as our krbtgt, it
+-		     * should exist in the local database.
+-		     *
+-		     */
+-
+-		    if (ret == HDB_ERR_NOENTRY)
+-			ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN;
+-		    msg = krb5_get_error_message(context, ret);
+-		    kdc_log(context, config, 1,
+-			    "S2U4Self principal to impersonate %s not found in database: %s",
+-			    tpn, msg);
+-		    krb5_free_error_message(context, msg);
+-		    goto out;
+-		}
+ 		ret = _kdc_pac_generate(context, s4u2self_impersonated_client, &p);
+ 		if (ret) {
+ 		    kdc_log(context, config, 0, "PAC generation failed for -- %s",
+@@ -1987,10 +1997,12 @@
+ 
+ 	    /*
+ 	     * If the service isn't trusted for authentication to
+-	     * delegation, remove the forward flag.
++	     * delegation or if the impersonate client is disallowed
++	     * forwardable, remove the forwardable flag.
+ 	     */
+ 
+-	    if (client->entry.flags.trusted_for_delegation) {
++	    if (client->entry.flags.trusted_for_delegation &&
++		s4u2self_impersonated_client->entry.flags.forwardable) {
+ 		str = "[forwardable]";
+ 	    } else {
+ 		b->kdc_options.forwardable = 0;
+--- crypto/heimdal/kdc/kstash.c.orig
++++ crypto/heimdal/kdc/kstash.c
+@@ -126,6 +126,8 @@
+ 	    krb5_string_to_key_salt(context, enctype, buf, salt, &key);
+ 	}
+ 	ret = hdb_add_master_key(context, &key, &mkey);
++        if (ret)
++            krb5_err(context, 1, ret, "hdb_add_master_key");
+ 
+ 	krb5_free_keyblock_contents(context, &key);
+ 
+--- crypto/heimdal/kdc/pkinit.c.orig
++++ crypto/heimdal/kdc/pkinit.c
+@@ -249,7 +249,6 @@
+ 	    memset(dh_gen_key, 0, size);
+ 	}
+ 
+-	ret = 0;
+ #ifdef HAVE_OPENSSL
+     } else if (client_params->keyex == USE_ECDH) {
+ 
+--- crypto/heimdal/kuser/kdestroy.c.orig
++++ crypto/heimdal/kuser/kdestroy.c
+@@ -90,7 +90,9 @@
+     }
+ 
+     argc -= optidx;
++#ifndef __clang_analyzer__
+     argv += optidx;
++#endif
+ 
+     if (argc != 0)
+ 	usage (1);
+--- crypto/heimdal/kuser/kswitch.c.orig
++++ crypto/heimdal/kuser/kswitch.c
+@@ -86,14 +86,15 @@
+ 	    krb5_err(kcc_context, 1, ret, "krb5_cc_cache_get_first");
+ 
+ 	while (krb5_cc_cache_next(kcc_context, cursor, &id) == 0) {
+-	    krb5_principal p;
++	    krb5_principal p = NULL;
+ 	    char num[10];
+ 
+ 	    ret = krb5_cc_get_principal(kcc_context, id, &p);
++	    if (ret == 0)
++		ret = krb5_unparse_name(kcc_context, p, &name);
+ 	    if (ret)
+ 		continue;
+ 
+-	    ret = krb5_unparse_name(kcc_context, p, &name);
+ 	    krb5_free_principal(kcc_context, p);
+ 
+ 	    snprintf(num, sizeof(num), "%d", (int)(len + 1));
+--- crypto/heimdal/lib/asn1/der_copy.c.orig
++++ crypto/heimdal/lib/asn1/der_copy.c
+@@ -135,8 +135,12 @@
+ der_copy_octet_string (const heim_octet_string *from, heim_octet_string *to)
+ {
+     to->length = from->length;
+-    to->data   = malloc(to->length);
+-    if(to->length != 0 && to->data == NULL)
++    if (from->data == NULL) {
++        to->data = NULL;
++        return 0;
++    }
++    to->data = malloc(to->length);
++    if (to->length != 0 && to->data == NULL)
+ 	return ENOMEM;
+     memcpy(to->data, from->data, to->length);
+     return 0;
+--- crypto/heimdal/lib/asn1/gen_decode.c.orig
++++ crypto/heimdal/lib/asn1/gen_decode.c
+@@ -584,14 +584,14 @@
+ 		    classname(cl),
+ 		    ty ? "CONS" : "PRIM",
+ 		    valuename(cl, tag));
++	    fprintf(codefile,
++		    "(%s)->element = %s;\n",
++		    name, m->label);
+ 	    if (asprintf (&s, "%s(%s)->u.%s", m->optional ? "" : "&",
+ 			  name, m->gen_name) < 0 || s == NULL)
+ 		errx(1, "malloc");
+ 	    decode_type (s, m->type, m->optional, forwstr, m->gen_name, NULL,
+ 		depth + 1);
+-	    fprintf(codefile,
+-		    "(%s)->element = %s;\n",
+-		    name, m->label);
+ 	    free(s);
+ 	    fprintf(codefile,
+ 		    "}\n");
+@@ -600,23 +600,23 @@
+ 	if (have_ellipsis) {
+ 	    fprintf(codefile,
+ 		    "else {\n"
++		    "(%s)->element = %s;\n"
+ 		    "(%s)->u.%s.data = calloc(1, len);\n"
+ 		    "if ((%s)->u.%s.data == NULL) {\n"
+ 		    "e = ENOMEM; %s;\n"
+ 		    "}\n"
+ 		    "(%s)->u.%s.length = len;\n"
+ 		    "memcpy((%s)->u.%s.data, p, len);\n"
+-		    "(%s)->element = %s;\n"
+ 		    "p += len;\n"
+ 		    "ret += len;\n"
+ 		    "len = 0;\n"
+ 		    "}\n",
++		    name, have_ellipsis->label,
+ 		    name, have_ellipsis->gen_name,
+ 		    name, have_ellipsis->gen_name,
+ 		    forwstr,
+ 		    name, have_ellipsis->gen_name,
+-		    name, have_ellipsis->gen_name,
+-		    name, have_ellipsis->label);
++		    name, have_ellipsis->gen_name);
+ 	} else {
+ 	    fprintf(codefile,
+ 		    "else {\n"
+--- crypto/heimdal/lib/asn1/gen_free.c.orig
++++ crypto/heimdal/lib/asn1/gen_free.c
+@@ -61,6 +61,13 @@
+     case TNull:
+     case TGeneralizedTime:
+     case TUTCTime:
++        /*
++         * This doesn't do much, but it leaves zeros where garbage might
++         * otherwise have been found.  Gets us closer to having the equivalent
++         * of a memset()-to-zero data structure after calling the free
++         * functions.
++         */
++        fprintf(codefile, "*%s = 0;\n", name);
+ 	break;
+     case TBitString:
+ 	if (ASN1_TAILQ_EMPTY(t->members))
+--- crypto/heimdal/lib/gssapi/krb5/accept_sec_context.c.orig
++++ crypto/heimdal/lib/gssapi/krb5/accept_sec_context.c
+@@ -425,6 +425,7 @@
+ 	     * lets only send the error token on clock skew, that
+ 	     * limit when send error token for non-MUTUAL.
+ 	     */
++            free_Authenticator(ctx->auth_context->authenticator);
+ 	    return send_error_token(minor_status, context, kret,
+ 				    server, &indata, output_token);
+ 	} else if (kret) {
+--- crypto/heimdal/lib/gssapi/krb5/arcfour.c.orig
++++ crypto/heimdal/lib/gssapi/krb5/arcfour.c
+@@ -307,7 +307,7 @@
+ 	return GSS_S_FAILURE;
+     }
+ 
+-    cmp = ct_memcmp(cksum_data, p + 8, 8);
++    cmp = (ct_memcmp(cksum_data, p + 8, 8) == 0);
+     if (cmp) {
+ 	*minor_status = 0;
+ 	return GSS_S_BAD_MIC;
+@@ -331,9 +331,9 @@
+     _gsskrb5_decode_be_om_uint32(SND_SEQ, &seq_number);
+ 
+     if (context_handle->more_flags & LOCAL)
+-	cmp = memcmp(&SND_SEQ[4], "\xff\xff\xff\xff", 4);
++	cmp = (ct_memcmp(&SND_SEQ[4], "\xff\xff\xff\xff", 4) != 0);
+     else
+-	cmp = memcmp(&SND_SEQ[4], "\x00\x00\x00\x00", 4);
++	cmp = (ct_memcmp(&SND_SEQ[4], "\x00\x00\x00\x00", 4) != 0);
+ 
+     memset(SND_SEQ, 0, sizeof(SND_SEQ));
+     if (cmp != 0) {
+@@ -616,9 +616,9 @@
+     _gsskrb5_decode_be_om_uint32(SND_SEQ, &seq_number);
+ 
+     if (context_handle->more_flags & LOCAL)
+-	cmp = memcmp(&SND_SEQ[4], "\xff\xff\xff\xff", 4);
++	cmp = (ct_memcmp(&SND_SEQ[4], "\xff\xff\xff\xff", 4) != 0);
+     else
+-	cmp = memcmp(&SND_SEQ[4], "\x00\x00\x00\x00", 4);
++	cmp = (ct_memcmp(&SND_SEQ[4], "\x00\x00\x00\x00", 4) != 0);
+ 
+     if (cmp != 0) {
+ 	*minor_status = 0;
+@@ -695,7 +695,7 @@
+ 	return GSS_S_FAILURE;
+     }
+ 
+-    cmp = ct_memcmp(cksum_data, p0 + 16, 8); /* SGN_CKSUM */
++    cmp = (ct_memcmp(cksum_data, p0 + 16, 8) == 0); /* SGN_CKSUM */
+     if (cmp) {
+ 	_gsskrb5_release_buffer(minor_status, output_message_buffer);
+ 	*minor_status = 0;
+--- crypto/heimdal/lib/gssapi/krb5/decapsulate.c.orig
++++ crypto/heimdal/lib/gssapi/krb5/decapsulate.c
+@@ -54,6 +54,8 @@
+     e = der_get_length (p, total_len - 1, &len, &len_len);
+     if (e || 1 + len_len + len != total_len)
+ 	return -1;
++    if (total_len < 1 + len_len + 1)
++	return -1;
+     p += len_len;
+     if (*p++ != 0x06)
+ 	return -1;
+@@ -80,6 +82,10 @@
+ 
+     if (mech_len != mech->length)
+ 	return GSS_S_BAD_MECH;
++    if (mech_len > total_len)
++	return GSS_S_BAD_MECH;
++    if (p - *str > total_len - mech_len)
++	return GSS_S_BAD_MECH;
+     if (ct_memcmp(p,
+ 		  mech->elements,
+ 		  mech->length) != 0)
+@@ -190,13 +196,13 @@
+     size_t padlength;
+     int i;
+ 
+-    pad = (u_char *)wrapped_token->value + wrapped_token->length - 1;
+-    padlength = *pad;
++    pad = (u_char *)wrapped_token->value + wrapped_token->length;
++    padlength = pad[-1];
+ 
+     if (padlength > datalen)
+ 	return GSS_S_BAD_MECH;
+ 
+-    for (i = padlength; i > 0 && *pad == padlength; i--, pad--)
++    for (i = padlength; i > 0 && *--pad == padlength; i--)
+ 	;
+     if (i != 0)
+ 	return GSS_S_BAD_MIC;
+--- crypto/heimdal/lib/gssapi/krb5/unwrap.c.orig
++++ crypto/heimdal/lib/gssapi/krb5/unwrap.c
+@@ -64,6 +64,8 @@
+ 
+   if (IS_DCE_STYLE(context_handle)) {
+      token_len = 22 + 8 + 15; /* 45 */
++     if (input_message_buffer->length < token_len)
++	  return GSS_S_BAD_MECH;
+   } else {
+      token_len = input_message_buffer->length;
+   }
+@@ -76,6 +78,11 @@
+   if (ret)
+       return ret;
+ 
++  len = (p - (u_char *)input_message_buffer->value)
++      + 22 + 8;
++  if (input_message_buffer->length < len)
++      return GSS_S_BAD_MECH;
++
+   if (memcmp (p, "\x00\x00", 2) != 0)
+     return GSS_S_BAD_SIG;
+   p += 2;
+@@ -122,7 +129,7 @@
+   } else {
+     /* check pad */
+     ret = _gssapi_verify_pad(input_message_buffer,
+-			     input_message_buffer->length - len,
++			     input_message_buffer->length - len - 8,
+ 			     &padlength);
+     if (ret)
+         return ret;
+@@ -195,9 +202,10 @@
+   output_message_buffer->value  = malloc(output_message_buffer->length);
+   if(output_message_buffer->length != 0 && output_message_buffer->value == NULL)
+       return GSS_S_FAILURE;
+-  memcpy (output_message_buffer->value,
+-	  p + 24,
+-	  output_message_buffer->length);
++  if (output_message_buffer->value != NULL)
++      memcpy (output_message_buffer->value,
++	      p + 24,
++	      output_message_buffer->length);
+   return GSS_S_COMPLETE;
+ }
+ #endif
+@@ -230,6 +238,8 @@
+ 
+   if (IS_DCE_STYLE(context_handle)) {
+      token_len = 34 + 8 + 15; /* 57 */
++     if (input_message_buffer->length < token_len)
++	  return GSS_S_BAD_MECH;
+   } else {
+      token_len = input_message_buffer->length;
+   }
+@@ -242,7 +252,12 @@
+   if (ret)
+       return ret;
+ 
+-  if (memcmp (p, "\x04\x00", 2) != 0) /* HMAC SHA1 DES3_KD */
++  len = (p - (u_char *)input_message_buffer->value)
++      + 34 + 8;
++  if (input_message_buffer->length < len)
++      return GSS_S_BAD_MECH;
++
++  if (ct_memcmp (p, "\x04\x00", 2) != 0) /* HMAC SHA1 DES3_KD */
+     return GSS_S_BAD_SIG;
+   p += 2;
+   if (ct_memcmp (p, "\x02\x00", 2) == 0) {
+@@ -289,7 +304,7 @@
+   } else {
+     /* check pad */
+     ret = _gssapi_verify_pad(input_message_buffer,
+-			     input_message_buffer->length - len,
++			     input_message_buffer->length - len - 8,
+ 			     &padlength);
+     if (ret)
+         return ret;
+@@ -389,9 +404,10 @@
+   output_message_buffer->value  = malloc(output_message_buffer->length);
+   if(output_message_buffer->length != 0 && output_message_buffer->value == NULL)
+       return GSS_S_FAILURE;
+-  memcpy (output_message_buffer->value,
+-	  p + 36,
+-	  output_message_buffer->length);
++  if (output_message_buffer->value != NULL)
++      memcpy (output_message_buffer->value,
++	      p + 36,
++	      output_message_buffer->length);
+   return GSS_S_COMPLETE;
+ }
+ 
+--- crypto/heimdal/lib/gssapi/mech/gss_display_status.c.orig
++++ crypto/heimdal/lib/gssapi/mech/gss_display_status.c
+@@ -91,8 +91,7 @@
+ 	"Incorrect channel bindings were supplied",
+ 	"An invalid status code was supplied",
+ 	"A token had an invalid MIC",
+-	"No credentials were supplied, "
+-	"or the credentials were unavailable or inaccessible.",
++	"No credentials were supplied, or the credentials were unavailable or inaccessible.",
+ 	"No context has been established",
+ 	"A token was invalid",
+ 	"A credential was invalid",
+--- crypto/heimdal/lib/gssapi/mech/gss_import_name.c.orig
++++ crypto/heimdal/lib/gssapi/mech/gss_import_name.c
+@@ -113,7 +113,7 @@
+ 	len -= t;
+ 
+ 	t = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
+-	p += 4;
++	/* p += 4; */
+ 	len -= 4;
+ 
+ 	if (!composite && len != t)
+--- crypto/heimdal/lib/gssapi/mech/gss_mech_switch.c.orig
++++ crypto/heimdal/lib/gssapi/mech/gss_mech_switch.c
+@@ -137,6 +137,8 @@
+ 				}
+ 			}
+ 		}
++                if (byte_count == 0)
++                    return EINVAL;
+ 		if (!res) {
+ 			res = malloc(byte_count);
+ 			if (!res)
+--- crypto/heimdal/lib/gssapi/mech/mech_locl.h.orig
++++ crypto/heimdal/lib/gssapi/mech/mech_locl.h
+@@ -51,6 +51,7 @@
+ 
+ #include <roken.h>
+ 
++#include <krb5.h>
+ #include <gssapi.h>
+ #include <gssapi_mech.h>
+ #include <gssapi_krb5.h>
+--- crypto/heimdal/lib/gssapi/ntlm/init_sec_context.c.orig
++++ crypto/heimdal/lib/gssapi/ntlm/init_sec_context.c
+@@ -52,6 +52,8 @@
+ 	    continue;
+ 	str = NULL;
+ 	d = strtok_r(buf, ":", &str);
++	if (!d)
++	    continue;
+ 	if (d && strcasecmp(target_domain, d) != 0)
+ 	    continue;
+ 	u = strtok_r(NULL, ":", &str);
+--- crypto/heimdal/lib/gssapi/spnego/accept_sec_context.c.orig
++++ crypto/heimdal/lib/gssapi/spnego/accept_sec_context.c
+@@ -619,13 +619,15 @@
+ 	    if (ret == 0)
+ 		break;
+ 	}
+-	if (preferred_mech_type == GSS_C_NO_OID) {
+-	    HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+-	    free_NegotiationToken(&nt);
+-	    return ret;
+-	}
++    }
++
++    ctx->preferred_mech_type = preferred_mech_type;
+ 
+-	ctx->preferred_mech_type = preferred_mech_type;
++    if (preferred_mech_type == GSS_C_NO_OID) {
++        send_reject(minor_status, output_token);
++        HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
++        free_NegotiationToken(&nt);
++        return ret;
+     }
+ 
+     /*
+--- crypto/heimdal/lib/hdb/hdb-mitdb.c.orig
++++ crypto/heimdal/lib/hdb/hdb-mitdb.c
+@@ -720,7 +720,6 @@
+     krb5_error_code code;
+     krb5_data key;
+ 
+-    mdb_principal2key(context, principal, &key);
+     code = db->hdb__del(context, db, key);
+     krb5_data_free(&key);
+     return code;
+--- crypto/heimdal/lib/hx509/hxtool.c.orig
++++ crypto/heimdal/lib/hx509/hxtool.c
+@@ -1288,6 +1288,7 @@
+     const char *outfile = argv[0];
+ 
+     memset(&key, 0, sizeof(key));
++    memset(&signer, 0, sizeof(signer));
+ 
+     get_key(opt->key_string,
+ 	    opt->generate_key_string,
+--- crypto/heimdal/lib/hx509/ks_file.c.orig
++++ crypto/heimdal/lib/hx509/ks_file.c
+@@ -533,7 +533,7 @@
+ {
+     struct store_ctx *sc = ctx;
+     heim_octet_string data;
+-    int ret;
++    int ret = 0;
+ 
+     ret = hx509_cert_binary(context, c, &data);
+     if (ret)
+@@ -554,14 +554,14 @@
+ 					    HX509_KEY_FORMAT_DER, &data);
+ 	    if (ret)
+ 		break;
+-	    hx509_pem_write(context, _hx509_private_pem_name(key), NULL, sc->f,
+-			    data.data, data.length);
++            ret = hx509_pem_write(context, _hx509_private_pem_name(key), NULL,
++                                  sc->f, data.data, data.length);
+ 	    free(data.data);
+ 	}
+ 	break;
+     }
+ 
+-    return 0;
++    return ret;
+ }
+ 
+ static int
+--- crypto/heimdal/lib/hx509/name.c.orig
++++ crypto/heimdal/lib/hx509/name.c
+@@ -938,6 +938,7 @@
+ hx509_general_name_unparse(GeneralName *name, char **str)
+ {
+     struct rk_strpool *strpool = NULL;
++    int ret = 0;
+ 
+     *str = NULL;
+ 
+@@ -964,7 +965,6 @@
+     case choice_GeneralName_directoryName: {
+ 	Name dir;
+ 	char *s;
+-	int ret;
+ 	memset(&dir, 0, sizeof(dir));
+ 	dir.element = name->u.directoryName.element;
+ 	dir.u.rdnSequence = name->u.directoryName.u.rdnSequence;
+@@ -1017,10 +1017,9 @@
+     default:
+ 	return EINVAL;
+     }
+-    if (strpool == NULL)
++    if (ret)
++        rk_strpoolfree(strpool);
++    else if (strpool == NULL || (*str = rk_strpoolcollect(strpool)) == NULL)
+ 	return ENOMEM;
+-
+-    *str = rk_strpoolcollect(strpool);
+-
+-    return 0;
++    return ret;
+ }
+--- crypto/heimdal/lib/hx509/softp11.c.orig
++++ crypto/heimdal/lib/hx509/softp11.c
+@@ -342,6 +342,9 @@
+     struct st_attr *a;
+     int i;
+ 
++    if (pValue == NULL && ulValueLen)
++        return CKR_ARGUMENTS_BAD;
++
+     i = o->num_attributes;
+     a = realloc(o->attrs, (i + 1) * sizeof(o->attrs[0]));
+     if (a == NULL)
+@@ -352,7 +355,8 @@
+     o->attrs[i].attribute.pValue = malloc(ulValueLen);
+     if (o->attrs[i].attribute.pValue == NULL && ulValueLen != 0)
+ 	return CKR_DEVICE_MEMORY;
+-    memcpy(o->attrs[i].attribute.pValue, pValue, ulValueLen);
++    if (ulValueLen)
++        memcpy(o->attrs[i].attribute.pValue, pValue, ulValueLen);
+     o->attrs[i].attribute.ulValueLen = ulValueLen;
+     o->num_attributes++;
+ 
+--- crypto/heimdal/lib/ipc/client.c.orig
++++ crypto/heimdal/lib/ipc/client.c
+@@ -332,10 +332,8 @@
+ 	return errno;
+     rk_cloexec(s->fd);
+ 
+-    if (connect(s->fd, (struct sockaddr *)&addr, sizeof(addr)) != 0) {
+-	close(s->fd);
++    if (connect(s->fd, (struct sockaddr *)&addr, sizeof(addr)) != 0)
+ 	return errno;
+-    }
+ 
+     return 0;
+ }
+--- crypto/heimdal/lib/kadm5/get_s.c.orig
++++ crypto/heimdal/lib/kadm5/get_s.c
+@@ -246,7 +246,7 @@
+ 	    ret = hdb_entry_get_password(context->context,
+ 					 context->db, &ent.entry, &pw);
+ 	    if (ret == 0) {
+-		ret = add_tl_data(out, KRB5_TL_PASSWORD, pw, strlen(pw) + 1);
++		(void) add_tl_data(out, KRB5_TL_PASSWORD, pw, strlen(pw) + 1);
+ 		free(pw);
+ 	    }
+ 	    krb5_clear_error_message(context->context);
+--- crypto/heimdal/lib/kadm5/init_c.c.orig
++++ crypto/heimdal/lib/kadm5/init_c.c
+@@ -567,7 +567,7 @@
+ 			  void **server_handle)
+ {
+     kadm5_ret_t ret;
+-    kadm5_client_context *ctx;
++    kadm5_client_context *ctx = NULL;
+     krb5_ccache cc;
+ 
+     ret = _kadm5_c_init_context(&ctx, realm_params, context);
+--- crypto/heimdal/lib/kadm5/ipropd_master.c.orig
++++ crypto/heimdal/lib/kadm5/ipropd_master.c
+@@ -755,7 +755,10 @@
+ 	    rtbl_add_column_entry(tbl, SLAVE_STATUS, "Up");
+ 
+ 	ret = krb5_format_time(context, slaves->seen, str, sizeof(str), TRUE);
+-	rtbl_add_column_entry(tbl, SLAVE_SEEN, str);
++        if (ret)
++            rtbl_add_column_entry(tbl, SLAVE_SEEN, "<error-formatting-time>");
++        else
++            rtbl_add_column_entry(tbl, SLAVE_SEEN, str);
+ 
+ 	slaves = slaves->next;
+     }
+--- crypto/heimdal/lib/kafs/afskrb5.c.orig
++++ crypto/heimdal/lib/kafs/afskrb5.c
+@@ -89,8 +89,6 @@
*** 655 LINES SKIPPED ***