diff --git a/backport-Allow-modifications-of-empty-profiles.patch b/backport-Allow-modifications-of-empty-profiles.patch new file mode 100644 index 0000000000000000000000000000000000000000..bca8e4c885acbe1627ac52154027352a018089cd --- /dev/null +++ b/backport-Allow-modifications-of-empty-profiles.patch @@ -0,0 +1,187 @@ +From fc54edd1dc047aedb211beaa544c5e000fbdb7a6 Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Sun, 31 Mar 2024 12:30:18 -0400 +Subject: [PATCH] Allow modifications of empty profiles + +Add the notion of a memory-only prf_data_t object, indicated by an +empty filespec field and appropriate flags (do not reload, always +dirty, not part of shared trees). Do nothing when flushing a +memory-only data object to its backing file. When setting up an empty +profile for read/write access, create a memory-only data object +instead of crashing. + +Move prf_data_t mutex initialization into profile_make_prf_data(), +simplifying its callers. + +ticket: 9110 + +Conflict:Don't modify the src/util/profile/t_profile.c file because it does not exist. +Reference:https://github.com/krb5/krb5/commit/fc54edd1dc047aedb211beaa544c5e000fbdb7a6 + +--- + src/util/profile/prof_file.c | 46 ++++++++++++++++++++++++++++++------ + src/util/profile/prof_int.h | 2 ++ + src/util/profile/prof_set.c | 33 +++++++++++--------------- + 3 files changed, 55 insertions(+), 26 deletions(-) + +diff --git a/src/util/profile/prof_file.c b/src/util/profile/prof_file.c +index aa951df05..b5eddc0d9 100644 +--- a/src/util/profile/prof_file.c ++++ b/src/util/profile/prof_file.c +@@ -159,6 +159,10 @@ profile_make_prf_data(const char *filename) + d->root = NULL; + d->next = NULL; + d->fslen = flen; ++ if (k5_mutex_init(&d->lock) != 0) { ++ free(d); ++ return NULL; ++ } + return d; + } + +@@ -239,13 +243,6 @@ errcode_t profile_open_file(const_profile_filespec_t filespec, + free(expanded_filename); + prf->data = data; + +- retval = k5_mutex_init(&data->lock); +- if (retval) { +- free(data); +- free(prf); +- return retval; +- } +- + retval = profile_update_file(prf, ret_modspec); + if (retval) { + profile_close_file(prf); +@@ -262,6 +259,37 @@ errcode_t profile_open_file(const_profile_filespec_t filespec, + return 0; + } + ++prf_file_t profile_open_memory(void) ++{ ++ struct profile_node *root = NULL; ++ prf_file_t file = NULL; ++ prf_data_t data; ++ ++ file = calloc(1, sizeof(*file)); ++ if (file == NULL) ++ goto errout; ++ file->magic = PROF_MAGIC_FILE; ++ ++ if (profile_create_node("(root)", NULL, &root) != 0) ++ goto errout; ++ ++ data = profile_make_prf_data(""); ++ if (data == NULL) ++ goto errout; ++ ++ data->root = root; ++ data->flags = PROFILE_FILE_NO_RELOAD | PROFILE_FILE_DIRTY; ++ file->data = data; ++ file->next = NULL; ++ return file; ++ ++errout: ++ free(file); ++ if (root != NULL) ++ profile_free_node(root); ++ return NULL; ++} ++ + errcode_t profile_update_file_data_locked(prf_data_t data, char **ret_modspec) + { + errcode_t retval; +@@ -468,6 +496,10 @@ errcode_t profile_flush_file_data(prf_data_t data) + if (!data || data->magic != PROF_MAGIC_FILE_DATA) + return PROF_MAGIC_FILE_DATA; + ++ /* Do nothing if this data object has no backing file. */ ++ if (*data->filespec == '\0') ++ return 0; ++ + k5_mutex_lock(&data->lock); + + if ((data->flags & PROFILE_FILE_DIRTY) == 0) { +diff --git a/src/util/profile/prof_int.h b/src/util/profile/prof_int.h +index 1ee9a8ca1..21c535a5c 100644 +--- a/src/util/profile/prof_int.h ++++ b/src/util/profile/prof_int.h +@@ -214,6 +214,8 @@ errcode_t profile_open_file + (const_profile_filespec_t file, prf_file_t *ret_prof, + char **ret_modspec); + ++prf_file_t profile_open_memory(void); ++ + #define profile_update_file(P, M) profile_update_file_data((P)->data, M) + errcode_t profile_update_file_data + (prf_data_t profile, char **ret_modspec); +diff --git a/src/util/profile/prof_set.c b/src/util/profile/prof_set.c +index af4b2f853..aeea676cb 100644 +--- a/src/util/profile/prof_set.c ++++ b/src/util/profile/prof_set.c +@@ -24,7 +24,7 @@ + static errcode_t rw_setup(profile_t profile) + { + prf_file_t file; +- errcode_t retval = 0; ++ prf_data_t new_data; + + if (!profile) + return PROF_NO_PROFILE; +@@ -32,6 +32,12 @@ static errcode_t rw_setup(profile_t profile) + if (profile->magic != PROF_MAGIC_PROFILE) + return PROF_MAGIC_PROFILE; + ++ /* If the profile has no files, create a memory-only data object. */ ++ if (profile->first_file == NULL) { ++ profile->first_file = profile_open_memory(); ++ return (profile->first_file == NULL) ? ENOMEM : 0; ++ } ++ + file = profile->first_file; + + profile_lock_global(); +@@ -43,33 +49,22 @@ static errcode_t rw_setup(profile_t profile) + } + + if ((file->data->flags & PROFILE_FILE_SHARED) != 0) { +- prf_data_t new_data; + new_data = profile_make_prf_data(file->data->filespec); + if (new_data == NULL) { +- retval = ENOMEM; +- } else { +- retval = k5_mutex_init(&new_data->lock); +- if (retval == 0) { +- new_data->root = NULL; +- new_data->flags = file->data->flags & ~PROFILE_FILE_SHARED; +- new_data->timestamp = 0; +- new_data->upd_serial = file->data->upd_serial; +- } +- } +- +- if (retval != 0) { + profile_unlock_global(); +- free(new_data); +- return retval; ++ return ENOMEM; + } ++ new_data->root = NULL; ++ new_data->flags = file->data->flags & ~PROFILE_FILE_SHARED; ++ new_data->timestamp = 0; ++ new_data->upd_serial = file->data->upd_serial; ++ + profile_dereference_data_locked(file->data); + file->data = new_data; + } + + profile_unlock_global(); +- retval = profile_update_file(file, NULL); +- +- return retval; ++ return profile_update_file(file, NULL); + } + + +-- +2.33.0 + diff --git a/backport-Do-not-reload-a-modified-profile-data-object.patch b/backport-Do-not-reload-a-modified-profile-data-object.patch new file mode 100644 index 0000000000000000000000000000000000000000..455edf2a61552eceee87ec9fd036de5c14cb4830 --- /dev/null +++ b/backport-Do-not-reload-a-modified-profile-data-object.patch @@ -0,0 +1,54 @@ +From 9b2fb80ad24006784170875709a04dc79e03b401 Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Tue, 16 Apr 2024 02:14:29 -0400 +Subject: [PATCH] Do not reload a modified profile data object + +The profile library normally attempts to reload a profile data tree if +the backing file has changed. Reloading a dirty profile object +discards any modifications made by the caller. If we assume that the +modifications are destined to be flushed back out to the backing file, +then there is no good answer--one or the other set of changes will be +lost. But the caller may have a different intended use for the +modified tree (profile_flush_to_file(), profile_flush_to_buffer(), +krb5_init_context_profile()), for which the caller's modifications may +be critical. Avoid discarding in-memory edits to ensure the +correctness of these use cases. + +ticket: 9118 + +Conflict:NA +Reference:https://github.com/krb5/krb5/commit/9b2fb80ad24006784170875709a04dc79e03b401 + +--- + src/util/profile/prof_file.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/src/util/profile/prof_file.c b/src/util/profile/prof_file.c +index b5eddc0d9..a39a5dc18 100644 +--- a/src/util/profile/prof_file.c ++++ b/src/util/profile/prof_file.c +@@ -301,8 +301,13 @@ errcode_t profile_update_file_data_locked(prf_data_t data, char **ret_modspec) + FILE *f; + int isdir = 0; + ++ /* Don't reload if the backing file isn't a regular file. */ + if ((data->flags & PROFILE_FILE_NO_RELOAD) && data->root != NULL) + return 0; ++ /* Don't reload a modified data object, as the modifications may be ++ * important for this object's use. */ ++ if (data->flags & PROFILE_FILE_DIRTY) ++ return 0; + + #ifdef HAVE_STAT + now = time(0); +@@ -358,7 +363,6 @@ errcode_t profile_update_file_data_locked(prf_data_t data, char **ret_modspec) + } + + data->upd_serial++; +- data->flags &= ~PROFILE_FILE_DIRTY; + + if (isdir) { + retval = profile_process_directory(data->filespec, &data->root); +-- +2.33.0 + diff --git a/backport-Fix-two-unlikely-memory-leaks.patch b/backport-Fix-two-unlikely-memory-leaks.patch new file mode 100644 index 0000000000000000000000000000000000000000..b47a01a00ee276aa2b7b6adc6d2c0cc9a1c7f173 --- /dev/null +++ b/backport-Fix-two-unlikely-memory-leaks.patch @@ -0,0 +1,207 @@ +From c5f9c816107f70139de11b38aa02db2f1774ee0d Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Tue, 5 Mar 2024 19:53:07 -0500 +Subject: [PATCH] Fix two unlikely memory leaks + +In gss_krb5int_make_seal_token_v3(), one of the bounds checks (which +could probably never be triggered) leaks plain.data. Fix this leak +and use current practices for cleanup throughout the function. + +In xmt_rmtcallres() (unused within the tree and likely elsewhere), +store port_ptr into crp->port_ptr as soon as it is allocated; +otherwise it could leak if the subsequent xdr_u_int32() operation +fails. + +Conflict:Context adaptation in src/lib/rpc/pmap_rmt.c +Reference:https://github.com/krb5/krb5/commit/c5f9c816107f70139de11b38aa02db2f1774ee0d + +--- + src/lib/gssapi/krb5/k5sealv3.c | 56 +++++++++++++++------------------- + src/lib/rpc/pmap_rmt.c | 9 +++--- + 2 files changed, 29 insertions(+), 36 deletions(-) + +diff --git a/src/lib/gssapi/krb5/k5sealv3.c b/src/lib/gssapi/krb5/k5sealv3.c +index 3b4f8cb83..e881eee83 100644 +--- a/src/lib/gssapi/krb5/k5sealv3.c ++++ b/src/lib/gssapi/krb5/k5sealv3.c +@@ -65,7 +65,7 @@ gss_krb5int_make_seal_token_v3 (krb5_context context, + int conf_req_flag, int toktype) + { + size_t bufsize = 16; +- unsigned char *outbuf = 0; ++ unsigned char *outbuf = NULL; + krb5_error_code err; + int key_usage; + unsigned char acceptor_flag; +@@ -75,9 +75,13 @@ gss_krb5int_make_seal_token_v3 (krb5_context context, + #endif + size_t ec; + unsigned short tok_id; +- krb5_checksum sum; ++ krb5_checksum sum = { 0 }; + krb5_key key; + krb5_cksumtype cksumtype; ++ krb5_data plain = empty_data(); ++ ++ token->value = NULL; ++ token->length = 0; + + acceptor_flag = ctx->initiate ? 0 : FLAG_SENDER_IS_ACCEPTOR; + key_usage = (toktype == KG_TOK_WRAP_MSG +@@ -107,14 +111,15 @@ gss_krb5int_make_seal_token_v3 (krb5_context context, + #endif + + if (toktype == KG_TOK_WRAP_MSG && conf_req_flag) { +- krb5_data plain; + krb5_enc_data cipher; + size_t ec_max; + size_t encrypt_size; + + /* 300: Adds some slop. */ +- if (SIZE_MAX - 300 < message->length) +- return ENOMEM; ++ if (SIZE_MAX - 300 < message->length) { ++ err = ENOMEM; ++ goto cleanup; ++ } + ec_max = SIZE_MAX - message->length - 300; + if (ec_max > 0xffff) + ec_max = 0xffff; +@@ -126,20 +131,20 @@ gss_krb5int_make_seal_token_v3 (krb5_context context, + #endif + err = alloc_data(&plain, message->length + 16 + ec); + if (err) +- return err; ++ goto cleanup; + + /* Get size of ciphertext. */ + encrypt_size = krb5_encrypt_size(plain.length, key->keyblock.enctype); + if (encrypt_size > SIZE_MAX / 2) { + err = ENOMEM; +- goto error; ++ goto cleanup; + } + bufsize = 16 + encrypt_size; + /* Allocate space for header plus encrypted data. */ + outbuf = gssalloc_malloc(bufsize); + if (outbuf == NULL) { +- free(plain.data); +- return ENOMEM; ++ err = ENOMEM; ++ goto cleanup; + } + + /* TOK_ID */ +@@ -164,11 +169,8 @@ gss_krb5int_make_seal_token_v3 (krb5_context context, + cipher.ciphertext.length = bufsize - 16; + cipher.enctype = key->keyblock.enctype; + err = krb5_k_encrypt(context, key, key_usage, 0, &plain, &cipher); +- zap(plain.data, plain.length); +- free(plain.data); +- plain.data = 0; + if (err) +- goto error; ++ goto cleanup; + + /* Now that we know we're returning a valid token.... */ + ctx->seq_send++; +@@ -181,7 +183,6 @@ gss_krb5int_make_seal_token_v3 (krb5_context context, + /* If the rotate fails, don't worry about it. */ + #endif + } else if (toktype == KG_TOK_WRAP_MSG && !conf_req_flag) { +- krb5_data plain; + size_t cksumsize; + + /* Here, message is the application-supplied data; message2 is +@@ -193,21 +194,19 @@ gss_krb5int_make_seal_token_v3 (krb5_context context, + wrap_with_checksum: + err = alloc_data(&plain, message->length + 16); + if (err) +- return err; ++ goto cleanup; + + err = krb5_c_checksum_length(context, cksumtype, &cksumsize); + if (err) +- goto error; ++ goto cleanup; + + assert(cksumsize <= 0xffff); + + bufsize = 16 + message2->length + cksumsize; + outbuf = gssalloc_malloc(bufsize); + if (outbuf == NULL) { +- free(plain.data); +- plain.data = 0; + err = ENOMEM; +- goto error; ++ goto cleanup; + } + + /* TOK_ID */ +@@ -239,23 +238,15 @@ gss_krb5int_make_seal_token_v3 (krb5_context context, + if (message2->length) + memcpy(outbuf + 16, message2->value, message2->length); + +- sum.contents = outbuf + 16 + message2->length; +- sum.length = cksumsize; +- + err = krb5_k_make_checksum(context, cksumtype, key, + key_usage, &plain, &sum); +- zap(plain.data, plain.length); +- free(plain.data); +- plain.data = 0; + if (err) { + zap(outbuf,bufsize); +- goto error; ++ goto cleanup; + } + if (sum.length != cksumsize) + abort(); + memcpy(outbuf + 16 + message2->length, sum.contents, cksumsize); +- krb5_free_checksum_contents(context, &sum); +- sum.contents = 0; + /* Now that we know we're actually generating the token... */ + ctx->seq_send++; + +@@ -285,12 +276,13 @@ gss_krb5int_make_seal_token_v3 (krb5_context context, + + token->value = outbuf; + token->length = bufsize; +- return 0; ++ outbuf = NULL; ++ err = 0; + +-error: ++cleanup: ++ krb5_free_checksum_contents(context, &sum); ++ zapfree(plain.data, plain.length); + gssalloc_free(outbuf); +- token->value = NULL; +- token->length = 0; + return err; + } + +diff --git a/src/lib/rpc/pmap_rmt.c b/src/lib/rpc/pmap_rmt.c +index 434e4eea6..f55ca46c6 100644 +--- a/src/lib/rpc/pmap_rmt.c ++++ b/src/lib/rpc/pmap_rmt.c +@@ -160,11 +160,12 @@ xdr_rmtcallres( + caddr_t port_ptr; + + port_ptr = (caddr_t)(void *)crp->port_ptr; +- if (xdr_reference(xdrs, &port_ptr, sizeof (uint32_t), +- xdr_u_int32) && xdr_u_int32(xdrs, &crp->resultslen)) { +- crp->port_ptr = (uint32_t *)(void *)port_ptr; ++ if (!xdr_reference(xdrs, &port_ptr, sizeof (uint32_t), ++ (xdrproc_t)xdr_u_int32)) ++ return (FALSE); ++ crp->port_ptr = (uint32_t *)(void *)port_ptr; ++ if (xdr_u_int32(xdrs, &crp->resultslen)) + return ((*(crp->xdr_results))(xdrs, crp->results_ptr)); +- } + return (FALSE); + } + +-- +2.33.0 + diff --git a/krb5.spec b/krb5.spec index 4c46a9c23db8ab1d5bd1c5287d218b40104fd123..985b8262f34b6fda5b5b98da9e34b9533fca88dd 100644 --- a/krb5.spec +++ b/krb5.spec @@ -3,7 +3,7 @@ Name: krb5 Version: 1.19.2 -Release: 15 +Release: 16 Summary: The Kerberos network authentication protocol License: MIT URL: http://web.mit.edu/kerberos/www/ @@ -47,6 +47,9 @@ Patch23: backport-Avoid-small-read-overrun-in-UTF8-normalization.patch Patch24: backport-Use-memmove-in-Unicode-functions.patch Patch25: backport-In-PKINIT-check-for-null-PKCS7-enveloped-fields.patch Patch26: backport-Remove-klist-s-defname-global-variable.patch +Patch27: backport-Fix-two-unlikely-memory-leaks.patch +Patch28: backport-Allow-modifications-of-empty-profiles.patch +Patch29: backport-Do-not-reload-a-modified-profile-data-object.patch BuildRequires: gettext BuildRequires: gcc make automake autoconf pkgconfig pam-devel libselinux-devel byacc @@ -339,6 +342,9 @@ make -C src check || : %changelog +* Mon Jun 17 2024 gengqihu - 1.19.2-16 +- backport patches from upstream + * Tue Mar 19 2024 xuraoqing - 1.19.2-15 - backport patches from upstream