From a232588500d7aa39f884aad25a6a939a6373231d Mon Sep 17 00:00:00 2001 From: Linux_zhang Date: Tue, 25 Mar 2025 09:09:15 +0800 Subject: [PATCH] backport patches to fix bugs --- ...-module-leak-on-authentication-error.patch | 30 + backport-Fix-minor-logic-errors.patch | 517 ++++++++++++++++++ backport-Fix-type-violation-in-libkrad.patch | 62 +++ backport-Fix-various-small-logic-errors.patch | 90 +++ ...undefined-shift-in-decode_krb5_flags.patch | 38 ++ krb5.spec | 10 +- 6 files changed, 746 insertions(+), 1 deletion(-) create mode 100644 backport-Fix-LDAP-module-leak-on-authentication-error.patch create mode 100644 backport-Fix-minor-logic-errors.patch create mode 100644 backport-Fix-type-violation-in-libkrad.patch create mode 100644 backport-Fix-various-small-logic-errors.patch create mode 100644 backport-Prevent-undefined-shift-in-decode_krb5_flags.patch diff --git a/backport-Fix-LDAP-module-leak-on-authentication-error.patch b/backport-Fix-LDAP-module-leak-on-authentication-error.patch new file mode 100644 index 0000000..0c7f660 --- /dev/null +++ b/backport-Fix-LDAP-module-leak-on-authentication-error.patch @@ -0,0 +1,30 @@ +From 85c93922232300b0316546a2fc6dd93c7e2906cd Mon Sep 17 00:00:00 2001 +From: Feng Guo +Date: Thu, 28 Nov 2024 21:32:37 +0800 +Subject: [PATCH] Fix LDAP module leak on authentication error + +In initialize_server(), unbind the server handle if authenticate() +fails. + +[ghudson@mit.edu: rewrote commit message] + +ticket: 9153 (new) +--- + src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap_conn.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap_conn.c b/src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap_conn.c +index 5e77d5e49..d19e2b761 100644 +--- a/src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap_conn.c ++++ b/src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap_conn.c +@@ -189,6 +189,7 @@ initialize_server(krb5_ldap_context *ldap_context, krb5_ldap_server_info *info) + if (ret) { + info->server_status = OFF; + time(&info->downtime); ++ ldap_unbind_ext_s(server->ldap_handle, NULL, NULL); + free(server); + return ret; + } +-- +2.33.0 + diff --git a/backport-Fix-minor-logic-errors.patch b/backport-Fix-minor-logic-errors.patch new file mode 100644 index 0000000..57d91c2 --- /dev/null +++ b/backport-Fix-minor-logic-errors.patch @@ -0,0 +1,517 @@ +From e50f46b210ddafe85cc917e2571516ade46bc65f Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Sun, 17 Nov 2024 13:54:12 -0500 +Subject: [PATCH] Fix minor logic errors + +In k5_externalize_auth_context(), serialize the correct field when +remote_port is set. This is not a reachable bug because the function +is only accessible via gss_export_sec_context(), and the GSS library +does not set a remote port. + +In generic_gss_oid_to_str(), remove an inconsistently-applied test for +a null minor_status. Also remove minor_status null checks from +generic_gss_release_oid() and generic_gss_str_to_oid(), but add output +initializations and pointer checks to the API functions in g_oid_ops.c +in a similar manner to other GSSAPI functions. Remove +gssint_copy_oid_set() and replace its one call with a call to +generic_gss_copy_oid_set(). + +In the checksum functions, avoid crashing if the caller passes a null +key and checksum type 0. An error will be returned instead when +find_cksumtype() can't find the checksum type. +(krb5_k_verify_checksum() already had this check.) + +In pkinit_open_session(), remove an unnecessary null check for +ctx->p11_module_name, and add a check for p11name being null due to an +asprintf() failure. + +In profile_add_node(), add a check for null ret_node in the duplicate +subsection check. This is not a reachable bug because the function is +currently never called with null ret_node and null value. + +In ksu's main(), check for krb5_cc_default_name() returning NULL +(which only happens on allocation failure). Also clean up some +vestiges left behind by commit +9ebae7cb434b9b177c0af85c67a6d6267f46bc68. + +In ksu's get_authorized_princ_names(), close login_fp if we fail to +open k5users_path. + +In the KDC and kpropd write_pid_file(), avoid briefly leaking the file +handle on write failure. + +Reported by Valery Fedorenko. + +Conflict:src/lib/gssapi/mechglue/g_oid_ops.c,src/kdc/main.c + +--- + src/clients/ksu/heuristic.c | 5 +- + src/clients/ksu/main.c | 30 +++------- + src/kadmin/server/ovsec_kadmd.c | 26 +++------ + src/kdc/main.c | 9 +-- + src/kprop/kpropd.c | 7 ++- + src/lib/crypto/krb/make_checksum.c | 2 +- + src/lib/crypto/krb/make_checksum_iov.c | 2 +- + src/lib/crypto/krb/verify_checksum_iov.c | 2 +- + src/lib/gssapi/generic/oid_ops.c | 9 +-- + src/lib/gssapi/mechglue/g_oid_ops.c | 58 +++++++++++++++---- + src/lib/gssapi/mechglue/mglueP.h | 6 -- + src/lib/gssapi/spnego/spnego_mech.c | 2 +- + src/lib/krb5/krb/ser_actx.c | 2 +- + .../preauth/pkinit/pkinit_crypto_openssl.c | 30 +++++----- + src/util/profile/prof_tree.c | 3 +- + 15 files changed, 104 insertions(+), 89 deletions(-) + +diff --git a/src/clients/ksu/heuristic.c b/src/clients/ksu/heuristic.c +index 47baa78..962b794 100644 +--- a/src/clients/ksu/heuristic.c ++++ b/src/clients/ksu/heuristic.c +@@ -237,8 +237,11 @@ get_authorized_princ_names(luser, cmd, princ_list) + } + } + if (!k5users_flag){ +- if ((users_fp = fopen(k5users_path, "r")) == NULL) ++ users_fp = fopen(k5users_path, "r"); ++ if (users_fp == NULL) { ++ close_time(1, NULL, k5login_flag, login_fp); + return 0; ++ } + + if ( fowner(users_fp, pwd->pw_uid) == FALSE){ + close_time(k5users_flag,users_fp, k5login_flag,login_fp); +diff --git a/src/clients/ksu/main.c b/src/clients/ksu/main.c +index a7cb7ed..35ecf1b 100644 +--- a/src/clients/ksu/main.c ++++ b/src/clients/ksu/main.c +@@ -107,7 +107,6 @@ main (argc, argv) + + krb5_ccache cc_source = NULL; + const char * cc_source_tag = NULL; +- const char * cc_source_tag_tmp = NULL; + char * cmd = NULL, * exec_cmd = NULL; + int errflg = 0; + krb5_boolean auth_val; +@@ -281,23 +280,13 @@ main (argc, argv) + case 'c': + if (cc_source_tag == NULL) { + cc_source_tag = xstrdup(optarg); +- if ( strchr(cc_source_tag, ':')){ +- cc_source_tag_tmp = strchr(cc_source_tag, ':') + 1; +- +- if (!ks_ccache_name_is_initialized(ksu_context, +- cc_source_tag)) { +- com_err(prog_name, errno, +- _("while looking for credentials cache %s"), +- cc_source_tag_tmp); +- exit (1); +- } +- } +- else { +- fprintf(stderr, _("malformed credential cache name %s\n"), ++ if (!ks_ccache_name_is_initialized(ksu_context, ++ cc_source_tag)) { ++ com_err(prog_name, errno, ++ _("while looking for credentials cache %s"), + cc_source_tag); +- errflg++; ++ exit(1); + } +- + } else { + fprintf(stderr, _("Only one -c option allowed\n")); + errflg++; +@@ -381,11 +370,10 @@ main (argc, argv) + + if (cc_source_tag == NULL){ + cc_source_tag = krb5_cc_default_name(ksu_context); +- cc_source_tag_tmp = strchr(cc_source_tag, ':'); +- if (cc_source_tag_tmp == 0) +- cc_source_tag_tmp = cc_source_tag; +- else +- cc_source_tag_tmp++; ++ if (cc_source_tag == NULL) { ++ fprintf(stderr, _("ksu: failed to get default ccache name\n")); ++ exit(1); ++ } + } + + /* get a handle for the cache */ +diff --git a/src/kadmin/server/ovsec_kadmd.c b/src/kadmin/server/ovsec_kadmd.c +index 73d9bac..fe78ad6 100644 +--- a/src/kadmin/server/ovsec_kadmd.c ++++ b/src/kadmin/server/ovsec_kadmd.c +@@ -239,7 +239,7 @@ log_badverf(gss_name_t client_name, gss_name_t server_name, + OM_uint32 minor; + gss_buffer_desc client, server; + gss_OID gss_type; +- const char *a; ++ const char *a, *cname, *sname; + rpcproc_t proc; + unsigned int i; + const char *procname; +@@ -253,19 +253,11 @@ log_badverf(gss_name_t client_name, gss_name_t server_name, + + (void)gss_display_name(&minor, client_name, &client, &gss_type); + (void)gss_display_name(&minor, server_name, &server, &gss_type); +- if (client.value == NULL) { +- client.value = "(null)"; +- clen = sizeof("(null)") - 1; +- } else { +- clen = client.length; +- } ++ cname = (client.value == NULL) ? "(null)" : client.value; ++ clen = (client.value == NULL) ? sizeof("(null)") - 1 : client.length; + trunc_name(&clen, &cdots); +- if (server.value == NULL) { +- server.value = "(null)"; +- slen = sizeof("(null)") - 1; +- } else { +- slen = server.length; +- } ++ sname = (server.value == NULL) ? "(null)" : server.value; ++ slen = (server.value == NULL) ? sizeof("(null)") - 1 : server.length; + trunc_name(&slen, &sdots); + a = client_addr(rqst->rq_xprt); + +@@ -281,14 +273,14 @@ log_badverf(gss_name_t client_name, gss_name_t server_name, + krb5_klog_syslog(LOG_NOTICE, + _("WARNING! Forged/garbled request: %s, claimed " + "client = %.*s%s, server = %.*s%s, addr = %s"), +- procname, (int)clen, (char *)client.value, cdots, +- (int)slen, (char *)server.value, sdots, a); ++ procname, (int)clen, cname, cdots, (int)slen, sname, ++ sdots, a); + } else { + krb5_klog_syslog(LOG_NOTICE, + _("WARNING! Forged/garbled request: %d, claimed " + "client = %.*s%s, server = %.*s%s, addr = %s"), +- proc, (int)clen, (char *)client.value, cdots, +- (int)slen, (char *)server.value, sdots, a); ++ proc, (int)clen, cname, cdots, (int)slen, sname, ++ sdots, a); + } + + (void)gss_release_buffer(&minor, &client); +diff --git a/src/kdc/main.c b/src/kdc/main.c +index d30e6cd..f11f141 100644 +--- a/src/kdc/main.c ++++ b/src/kdc/main.c +@@ -871,14 +871,15 @@ write_pid_file(const char *path) + { + FILE *file; + unsigned long pid; ++ int st1, st2; + + file = WRITABLEFOPEN(path, "w"); + if (file == NULL) + return errno; +- pid = (unsigned long) getpid(); +- if (fprintf(file, "%ld\n", pid) < 0 || fclose(file) == EOF) +- return errno; +- return 0; ++ pid = (unsigned long)getpid(); ++ st1 = (fprintf(file, "%ld\n", pid) < 0) ? errno : 0; ++ st2 = (fclose(file) == EOF) ? errno : 0; ++ return st1 ? st1 : st2; + } + + static void +diff --git a/src/kprop/kpropd.c b/src/kprop/kpropd.c +index e0500d4..724ed95 100644 +--- a/src/kprop/kpropd.c ++++ b/src/kprop/kpropd.c +@@ -180,14 +180,15 @@ write_pid_file(const char *path) + { + FILE *fp; + unsigned long pid; ++ int st1, st2; + + fp = fopen(path, "w"); + if (fp == NULL) + return errno; + pid = (unsigned long)getpid(); +- if (fprintf(fp, "%ld\n", pid) < 0 || fclose(fp) == EOF) +- return errno; +- return 0; ++ st1 = (fprintf(fp, "%ld\n", pid) < 0) ? errno : 0; ++ st2 = (fclose(fp) == EOF) ? errno : 0; ++ return st1 ? st1 : st2; + } + + typedef void (*sig_handler_fn)(int sig); +diff --git a/src/lib/crypto/krb/make_checksum.c b/src/lib/crypto/krb/make_checksum.c +index 398c84a..3c57e41 100644 +--- a/src/lib/crypto/krb/make_checksum.c ++++ b/src/lib/crypto/krb/make_checksum.c +@@ -40,7 +40,7 @@ krb5_k_make_checksum(krb5_context context, krb5_cksumtype cksumtype, + krb5_octet *trunc; + krb5_error_code ret; + +- if (cksumtype == 0) { ++ if (cksumtype == 0 && key != NULL) { + ret = krb5int_c_mandatory_cksumtype(context, key->keyblock.enctype, + &cksumtype); + if (ret != 0) +diff --git a/src/lib/crypto/krb/make_checksum_iov.c b/src/lib/crypto/krb/make_checksum_iov.c +index 84e98b1..c9e9da8 100644 +--- a/src/lib/crypto/krb/make_checksum_iov.c ++++ b/src/lib/crypto/krb/make_checksum_iov.c +@@ -39,7 +39,7 @@ krb5_k_make_checksum_iov(krb5_context context, + krb5_crypto_iov *checksum; + const struct krb5_cksumtypes *ctp; + +- if (cksumtype == 0) { ++ if (cksumtype == 0 && key != NULL) { + ret = krb5int_c_mandatory_cksumtype(context, key->keyblock.enctype, + &cksumtype); + if (ret != 0) +diff --git a/src/lib/crypto/krb/verify_checksum_iov.c b/src/lib/crypto/krb/verify_checksum_iov.c +index 47a25a9..532e45c 100644 +--- a/src/lib/crypto/krb/verify_checksum_iov.c ++++ b/src/lib/crypto/krb/verify_checksum_iov.c +@@ -40,7 +40,7 @@ krb5_k_verify_checksum_iov(krb5_context context, + krb5_data computed; + krb5_crypto_iov *checksum; + +- if (checksum_type == 0) { ++ if (checksum_type == 0 && key != NULL) { + ret = krb5int_c_mandatory_cksumtype(context, key->keyblock.enctype, + &checksum_type); + if (ret != 0) +diff --git a/src/lib/gssapi/generic/oid_ops.c b/src/lib/gssapi/generic/oid_ops.c +index 253d646..0d65a95 100644 +--- a/src/lib/gssapi/generic/oid_ops.c ++++ b/src/lib/gssapi/generic/oid_ops.c +@@ -68,8 +68,7 @@ + OM_uint32 + generic_gss_release_oid(OM_uint32 *minor_status, gss_OID *oid) + { +- if (minor_status) +- *minor_status = 0; ++ *minor_status = 0; + + if (oid == NULL || *oid == GSS_C_NO_OID) + return(GSS_S_COMPLETE); +@@ -245,8 +244,7 @@ generic_gss_oid_to_str(OM_uint32 *minor_status, + unsigned char *cp; + struct k5buf buf; + +- if (minor_status != NULL) +- *minor_status = 0; ++ *minor_status = 0; + + if (oid_str != GSS_C_NO_BUFFER) { + oid_str->length = 0; +@@ -353,8 +351,7 @@ generic_gss_str_to_oid(OM_uint32 *minor_status, + int brace = 0; + gss_OID oid; + +- if (minor_status != NULL) +- *minor_status = 0; ++ *minor_status = 0; + + if (oid_out != NULL) + *oid_out = GSS_C_NO_OID; +diff --git a/src/lib/gssapi/mechglue/g_oid_ops.c b/src/lib/gssapi/mechglue/g_oid_ops.c +index 1d7970c..035da76 100644 +--- a/src/lib/gssapi/mechglue/g_oid_ops.c ++++ b/src/lib/gssapi/mechglue/g_oid_ops.c +@@ -38,6 +38,13 @@ gss_create_empty_oid_set(minor_status, oid_set) + gss_OID_set *oid_set; + { + OM_uint32 status; ++ ++ if (minor_status != NULL) ++ *minor_status = 0; ++ if (oid_set != NULL) ++ *oid_set = GSS_C_NO_OID_SET; ++ if (minor_status == NULL || oid_set == NULL) ++ return GSS_S_CALL_INACCESSIBLE_WRITE; + status = generic_gss_create_empty_oid_set(minor_status, oid_set); + if (status != GSS_S_COMPLETE) + map_errcode(minor_status); +@@ -51,6 +58,14 @@ gss_add_oid_set_member(minor_status, member_oid, oid_set) + gss_OID_set *oid_set; + { + OM_uint32 status; ++ ++ if (minor_status != NULL) ++ *minor_status = 0; ++ if (minor_status == NULL || oid_set == NULL) ++ return GSS_S_CALL_INACCESSIBLE_WRITE; ++ if (member_oid == GSS_C_NO_OID || member_oid->length == 0 || ++ member_oid->elements == NULL) ++ return GSS_S_CALL_INACCESSIBLE_READ; + status = generic_gss_add_oid_set_member(minor_status, member_oid, oid_set); + if (status != GSS_S_COMPLETE) + map_errcode(minor_status); +@@ -64,6 +79,14 @@ gss_test_oid_set_member(minor_status, member, set, present) + gss_OID_set set; + int *present; + { ++ if (minor_status != NULL) ++ *minor_status = 0; ++ if (present != NULL) ++ *present = 0; ++ if (minor_status == NULL || present == NULL) ++ return GSS_S_CALL_INACCESSIBLE_WRITE; ++ if (member == GSS_C_NO_OID || set == GSS_C_NO_OID_SET) ++ return GSS_S_CALL_INACCESSIBLE_READ; + return generic_gss_test_oid_set_member(minor_status, member, set, present); + } + +@@ -73,7 +96,19 @@ gss_oid_to_str(minor_status, oid, oid_str) + gss_OID oid; + gss_buffer_t oid_str; + { +- OM_uint32 status = generic_gss_oid_to_str(minor_status, oid, oid_str); ++ OM_uint32 status; ++ ++ if (minor_status != NULL) ++ *minor_status = 0; ++ if (oid_str != GSS_C_NO_BUFFER) { ++ oid_str->length = 0; ++ oid_str->value = NULL; ++ } ++ if (minor_status == NULL || oid_str == GSS_C_NO_BUFFER) ++ return GSS_S_CALL_INACCESSIBLE_WRITE; ++ if (oid == GSS_C_NO_OID || oid->length == 0 || oid->elements == NULL) ++ return GSS_S_CALL_INACCESSIBLE_READ; ++ status = generic_gss_oid_to_str(minor_status, oid, oid_str); + if (status != GSS_S_COMPLETE) + map_errcode(minor_status); + return status; +@@ -85,21 +120,22 @@ gss_str_to_oid(minor_status, oid_str, oid) + gss_buffer_t oid_str; + gss_OID *oid; + { +- OM_uint32 status = generic_gss_str_to_oid(minor_status, oid_str, oid); ++ OM_uint32 status; ++ ++ if (minor_status != NULL) ++ *minor_status = 0; ++ if (oid != NULL) ++ *oid = GSS_C_NO_OID; ++ if (minor_status == NULL || oid == NULL) ++ return GSS_S_CALL_INACCESSIBLE_WRITE; ++ if (GSS_EMPTY_BUFFER(oid_str)) ++ return GSS_S_CALL_INACCESSIBLE_READ; ++ status = generic_gss_str_to_oid(minor_status, oid_str, oid); + if (status != GSS_S_COMPLETE) + map_errcode(minor_status); + return status; + } + +-OM_uint32 +-gssint_copy_oid_set( +- OM_uint32 *minor_status, +- const gss_OID_set_desc * const oidset, +- gss_OID_set *new_oidset) +-{ +- return generic_gss_copy_oid_set(minor_status, oidset, new_oidset); +-} +- + int KRB5_CALLCONV + gss_oid_equal( + gss_const_OID first_oid, +diff --git a/src/lib/gssapi/mechglue/mglueP.h b/src/lib/gssapi/mechglue/mglueP.h +index 2b65939..f66a54a 100644 +--- a/src/lib/gssapi/mechglue/mglueP.h ++++ b/src/lib/gssapi/mechglue/mglueP.h +@@ -806,12 +806,6 @@ OM_uint32 gssint_create_union_context( + gss_union_ctx_id_t * /* ctx_out */ + ); + +-OM_uint32 gssint_copy_oid_set( +- OM_uint32 *, /* minor_status */ +- const gss_OID_set_desc * const, /* oid set */ +- gss_OID_set * /* new oid set */ +-); +- + gss_OID gss_find_mechanism_from_name_type (gss_OID); /* name_type */ + + OM_uint32 gss_add_mech_name_type +diff --git a/src/lib/gssapi/spnego/spnego_mech.c b/src/lib/gssapi/spnego/spnego_mech.c +index 654964c..f8b50d8 100644 +--- a/src/lib/gssapi/spnego/spnego_mech.c ++++ b/src/lib/gssapi/spnego/spnego_mech.c +@@ -401,7 +401,7 @@ spnego_gss_acquire_cred_from(OM_uint32 *minor_status, + &amechs, time_rec); + + if (actual_mechs && amechs != GSS_C_NULL_OID_SET) { +- (void) gssint_copy_oid_set(&tmpmin, amechs, actual_mechs); ++ (void) generic_gss_copy_oid_set(&tmpmin, amechs, actual_mechs); + } + (void) gss_release_oid_set(&tmpmin, &amechs); + +diff --git a/src/lib/krb5/krb/ser_actx.c b/src/lib/krb5/krb/ser_actx.c +index 6de35a1..ed8e255 100644 +--- a/src/lib/krb5/krb/ser_actx.c ++++ b/src/lib/krb5/krb/ser_actx.c +@@ -171,7 +171,7 @@ k5_externalize_auth_context(krb5_auth_context auth_context, + /* Now handle remote_port, if appropriate */ + if (!kret && auth_context->remote_port) { + (void) krb5_ser_pack_int32(TOKEN_RPORT, &bp, &remain); +- kret = k5_externalize_address(auth_context->remote_addr, ++ kret = k5_externalize_address(auth_context->remote_port, + &bp, &remain); + } + +diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c +index f2e4dcb..3a98980 100644 +--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c ++++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c +@@ -3735,20 +3735,22 @@ pkinit_open_session(krb5_context context, + + /* Login if needed */ + if (tinfo.flags & CKF_LOGIN_REQUIRED) { +- if (cctx->p11_module_name != NULL) { +- if (cctx->slotid != PK_NOSLOT) { +- if (asprintf(&p11name, +- "PKCS11:module_name=%s:slotid=%ld:token=%.*s", +- cctx->p11_module_name, (long)cctx->slotid, +- (int)label_len, tinfo.label) < 0) +- p11name = NULL; +- } else { +- if (asprintf(&p11name, +- "PKCS11:module_name=%s,token=%.*s", +- cctx->p11_module_name, +- (int)label_len, tinfo.label) < 0) +- p11name = NULL; +- } ++ if (cctx->slotid != PK_NOSLOT) { ++ if (asprintf(&p11name, ++ "PKCS11:module_name=%s:slotid=%ld:token=%.*s", ++ cctx->p11_module_name, (long)cctx->slotid, ++ (int)label_len, tinfo.label) < 0) ++ p11name = NULL; ++ } else { ++ if (asprintf(&p11name, ++ "PKCS11:module_name=%s,token=%.*s", ++ cctx->p11_module_name, ++ (int)label_len, tinfo.label) < 0) ++ p11name = NULL; ++ } ++ if (p11name == NULL) { ++ ret = ENOMEM; ++ goto cleanup; + } + if (cctx->defer_id_prompt) { + /* Supply the identity name to be passed to the responder. */ +diff --git a/src/util/profile/prof_tree.c b/src/util/profile/prof_tree.c +index b3c15ca..cecd33e 100644 +--- a/src/util/profile/prof_tree.c ++++ b/src/util/profile/prof_tree.c +@@ -172,7 +172,8 @@ errcode_t profile_add_node(struct profile_node *section, const char *name, + } else if (value == NULL && cmp == 0 && + p->value == NULL && p->deleted != 1) { + /* Found duplicate subsection, so don't make a new one. */ +- *ret_node = p; ++ if (ret_node) ++ *ret_node = p; + return 0; + } + } +-- +2.33.0 + diff --git a/backport-Fix-type-violation-in-libkrad.patch b/backport-Fix-type-violation-in-libkrad.patch new file mode 100644 index 0000000..661c5e0 --- /dev/null +++ b/backport-Fix-type-violation-in-libkrad.patch @@ -0,0 +1,62 @@ +From aac785e5e050415f8b8cb29059d2f658f755e7e7 Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Mon, 28 Oct 2024 11:51:54 -0400 +Subject: [PATCH] Fix type violation in libkrad + +remote.c uses casts to cover up a signature difference between +iterator() and krad_packet_iter_cb. The difference is unimportant in +typical platform ABIs, but calling the function this way is undefined +behavior (C99 6.3.2.8). Fix iterator() to conform to +krad_packet_iter_cb and remove the casts. + +--- + src/lib/krad/remote.c | 15 +++++++-------- + 1 file changed, 7 insertions(+), 8 deletions(-) + +diff --git a/src/lib/krad/remote.c b/src/lib/krad/remote.c +index 06ae751..28f2e83 100644 +--- a/src/lib/krad/remote.c ++++ b/src/lib/krad/remote.c +@@ -76,15 +76,15 @@ on_timeout(verto_ctx *ctx, verto_ev *ev); + + /* Iterate over the set of outstanding packets. */ + static const krad_packet * +-iterator(request **out) ++iterator(void *data, krb5_boolean cancel) + { +- request *tmp = *out; ++ request **rptr = data, *req = *rptr; + +- if (tmp == NULL) ++ if (cancel || req == NULL) + return NULL; + +- *out = K5_TAILQ_NEXT(tmp, list); +- return tmp->request; ++ *rptr = K5_TAILQ_NEXT(req, list); ++ return req->request; + } + + /* Create a new request. */ +@@ -349,8 +349,7 @@ on_io_read(krad_remote *rr) + /* Decode the packet. */ + tmp = K5_TAILQ_FIRST(&rr->list); + retval = krad_packet_decode_response(rr->kctx, rr->secret, &rr->buffer, +- (krad_packet_iter_cb)iterator, &tmp, +- &req, &rsp); ++ iterator, &tmp, &req, &rsp); + rr->buffer.length = 0; + if (retval != 0) + return; +@@ -457,7 +456,7 @@ kr_remote_send(krad_remote *rr, krad_code code, krad_attrset *attrs, + + r = K5_TAILQ_FIRST(&rr->list); + retval = krad_packet_new_request(rr->kctx, rr->secret, code, attrs, +- (krad_packet_iter_cb)iterator, &r, &tmp); ++ iterator, &r, &tmp); + if (retval != 0) + goto error; + +-- +2.33.0 + diff --git a/backport-Fix-various-small-logic-errors.patch b/backport-Fix-various-small-logic-errors.patch new file mode 100644 index 0000000..255ec66 --- /dev/null +++ b/backport-Fix-various-small-logic-errors.patch @@ -0,0 +1,90 @@ +From 3b57de1b68f31fa297d91e8b00bd91587d71fd02 Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Fri, 1 Nov 2024 13:42:44 -0400 +Subject: [PATCH] Fix various small logic errors + +Correct five logic errors (all unlikely to manifest as user-visible +bugs) found by static analysis. Reported by Valery Fedorenko. +--- + src/kdc/policy.c | 2 +- + src/lib/apputils/net-server.c | 2 +- + src/lib/rpc/unit-test/client.c | 1 + + src/plugins/audit/kdc_j_encode.c | 10 ++++------ + src/plugins/preauth/pkinit/pkinit_crypto_openssl.c | 2 ++ + 5 files changed, 9 insertions(+), 8 deletions(-) + +diff --git a/src/kdc/policy.c b/src/kdc/policy.c +index a3ff556c5..1ae1c7a05 100644 +--- a/src/kdc/policy.c ++++ b/src/kdc/policy.c +@@ -180,7 +180,7 @@ unload_kdcpolicy_plugins(krb5_context context) + { + kdcpolicy_handle *hp, h; + +- for (hp = handles; *hp != NULL; hp++) { ++ for (hp = handles; hp != NULL && *hp != NULL; hp++) { + h = *hp; + if (h->vt.fini != NULL) + h->vt.fini(context, h->moddata); +diff --git a/src/lib/apputils/net-server.c b/src/lib/apputils/net-server.c +index 75372d894..b3da72d3f 100644 +--- a/src/lib/apputils/net-server.c ++++ b/src/lib/apputils/net-server.c +@@ -1127,7 +1127,7 @@ kill_lru_tcp_or_rpc_connection(void *handle, verto_ev *newev) + } + if (oldest_c != NULL) { + krb5_klog_syslog(LOG_INFO, _("dropping %s fd %d from %s"), +- c->type == CONN_RPC ? "rpc" : "tcp", ++ oldest_c->type == CONN_RPC ? "rpc" : "tcp", + verto_get_fd(oldest_ev), oldest_c->addrbuf); + if (oldest_c->type == CONN_RPC) + oldest_c->rpc_force_close = 1; +diff --git a/src/lib/rpc/unit-test/client.c b/src/lib/rpc/unit-test/client.c +index 9b907bcdc..7965a4306 100644 +--- a/src/lib/rpc/unit-test/client.c ++++ b/src/lib/rpc/unit-test/client.c +@@ -165,6 +165,7 @@ main(int argc, char **argv) + if (echo_resp == NULL) { + fprintf(stderr, "RPC_TEST_ECHO call %d%s", i, + clnt_sperror(clnt, "")); ++ break; + } + if (strncmp(*echo_resp, "Echo: ", 6) && + strcmp(echo_arg, (*echo_resp) + 6) != 0) +diff --git a/src/plugins/audit/kdc_j_encode.c b/src/plugins/audit/kdc_j_encode.c +index fb4a4ed73..0df258d76 100755 +--- a/src/plugins/audit/kdc_j_encode.c ++++ b/src/plugins/audit/kdc_j_encode.c +@@ -419,12 +419,10 @@ kau_j_tgs_u2u(const krb5_boolean ev_success, krb5_audit_state *state, + goto error; + } + /* Client in the second ticket. */ +- if (req != NULL) { +- ret = princ_to_value(req->second_ticket[0]->enc_part2->client, +- obj, AU_REQ_U2U_USER); +- if (ret) +- goto error; +- } ++ ret = princ_to_value(req->second_ticket[0]->enc_part2->client, ++ obj, AU_REQ_U2U_USER); ++ if (ret) ++ goto error; + /* Enctype of a session key of the second ticket. */ + ret = int32_to_value(req->second_ticket[0]->enc_part2->session->enctype, + obj, AU_SRV_ETYPE); +diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c +index 6d1966194..4ae2c00ad 100644 +--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c ++++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c +@@ -4110,6 +4110,8 @@ pkinit_get_certs_pkcs12(krb5_context context, + + TRACE_PKINIT_PKCS_PARSE_FAIL_FIRST(context); + ++ if (p12name == NULL) ++ goto cleanup; + if (id_cryptoctx->defer_id_prompt) { + /* Supply the identity name to be passed to the responder. */ + pkinit_set_deferred_id(&id_cryptoctx->deferred_ids, p12name, 0, +-- +2.33.0 + diff --git a/backport-Prevent-undefined-shift-in-decode_krb5_flags.patch b/backport-Prevent-undefined-shift-in-decode_krb5_flags.patch new file mode 100644 index 0000000..8c26828 --- /dev/null +++ b/backport-Prevent-undefined-shift-in-decode_krb5_flags.patch @@ -0,0 +1,38 @@ +From d09433aed821d40142b10dc5b4a0aa8110c5a09e Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Wed, 6 Nov 2024 17:31:37 -0500 +Subject: [PATCH] Prevent undefined shift in decode_krb5_flags() + +In the statement "f |= bits[i] << (8 * (3 - i))", bits[i] is +implicitly promoted from uint8_t to int according to the integer +promotion rules (C99 6.3.1.1). If i is 0 and bits[i] >= 128, the +result cannot be represented as an int and the behavior of the shift +is undefined (C99 6.5.7). To ensure that the shift operation is +defined, cast bits[i] to uint32_t. + +(f and the function output are int32_t, but the conversion of uint32_t +to int32_t is implementation-defined when the value cannot be +represented, not undefined. We check in configure.ac that the +platform is two's complement.) + +(Discovered by OSS-Fuzz.) +--- + src/lib/krb5/asn.1/asn1_k_encode.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/lib/krb5/asn.1/asn1_k_encode.c b/src/lib/krb5/asn.1/asn1_k_encode.c +index ad5a18a24..1a250c98c 100644 +--- a/src/lib/krb5/asn.1/asn1_k_encode.c ++++ b/src/lib/krb5/asn.1/asn1_k_encode.c +@@ -250,7 +250,7 @@ decode_krb5_flags(const taginfo *t, const uint8_t *asn1, size_t len, void *val) + return ret; + /* Copy up to 32 bits into f, starting at the most significant byte. */ + for (i = 0; i < blen && i < 4; i++) +- f |= bits[i] << (8 * (3 - i)); ++ f |= (uint32_t)bits[i] << (8 * (3 - i)); + *(krb5_flags *)val = f; + free(bits); + return 0; +-- +2.33.0 + diff --git a/krb5.spec b/krb5.spec index 1748eb3..e1f6756 100644 --- a/krb5.spec +++ b/krb5.spec @@ -3,7 +3,7 @@ Name: krb5 Version: 1.21.2 -Release: 14 +Release: 15 Summary: The Kerberos network authentication protocol License: MIT URL: http://web.mit.edu/kerberos/www/ @@ -49,6 +49,11 @@ Patch25: backport-Fix-various-issues-detected-by-static-analysis.patch Patch26: backport-Fix-krb5_crypto_us_timeofday-microseconds-check.patch Patch27: backport-Prevent-late-initialization-of-GSS-error-map.patch Patch28: backport-CVE-2025-24528.patch +Patch29: backport-Fix-LDAP-module-leak-on-authentication-error.patch +Patch30: backport-Fix-minor-logic-errors.patch +Patch31: backport-Fix-type-violation-in-libkrad.patch +Patch32: backport-Fix-various-small-logic-errors.patch +Patch33: backport-Prevent-undefined-shift-in-decode_krb5_flags.patch BuildRequires: gettext BuildRequires: gcc make automake autoconf pkgconfig pam-devel libselinux-devel byacc @@ -333,6 +338,9 @@ make -C src check || : %{_mandir}/man8/* %changelog +* Tue Mar 25 2025 Linux_zhang - 1.21.2-15 +- backport patches to fix bugs + * Thu Jan 30 2025 Funda Wang - 1.21.2-14 - fix CVE-2025-24528 -- Gitee