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 ***