git: 6bc209f5dd - main - Add SA-22:14.
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
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 ***