From ghudson at mit.edu Fri Sep 4 19:31:37 2026 From: ghudson at mit.edu (ghudson at mit.edu) Date: Fri, 4 Sep 2026 19:31:37 -0400 (EDT) Subject: krb5 commit: Prevent dangling result in tl_data2berval() Message-ID: <20260904233137.52D671016EB@krbdev.mit.edu> https://github.com/krb5/krb5/commit/6a880f5a629ccdfe9e5ecefc46b2186ba69bcc6d commit 6a880f5a629ccdfe9e5ecefc46b2186ba69bcc6d Author: Greg Hudson Date: Mon Aug 31 17:56:46 2026 -0400 Prevent dangling result in tl_data2berval() If the second malloc() fails in tl_data2berval(), do not leave a dangling freed pointer in *out, or the caller will free it a second time. Reported by Vidal Segura Garc??a. ticket: 9232 tags: pullup target_version: 1.22-next src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c b/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c index 9aa68bacd..5bacaee28 100644 --- a/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c +++ b/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c @@ -628,20 +628,24 @@ cleanup: static krb5_error_code tl_data2berval (krb5_tl_data *in, struct berval **out) { - *out = (struct berval *) malloc (sizeof (struct berval)); - if (*out == NULL) - return ENOMEM; + struct berval *bv; - (*out)->bv_len = in->tl_data_length + 2; - (*out)->bv_val = (char *) malloc ((*out)->bv_len); - if ((*out)->bv_val == NULL) { - free (*out); + *out = NULL; + + bv = malloc(sizeof(*bv)); + if (bv == NULL) + return ENOMEM; + bv->bv_len = in->tl_data_length + 2; + bv->bv_val = malloc(bv->bv_len); + if (bv->bv_val == NULL) { + free(bv); return ENOMEM; } - STORE16_INT((*out)->bv_val, in->tl_data_type); - k5memcpy((*out)->bv_val + 2, in->tl_data_contents, in->tl_data_length); + STORE16_INT(bv->bv_val, in->tl_data_type); + k5memcpy(bv->bv_val + 2, in->tl_data_contents, in->tl_data_length); + *out = bv; return 0; } From ghudson at mit.edu Fri Sep 4 19:47:49 2026 From: ghudson at mit.edu (ghudson at mit.edu) Date: Fri, 4 Sep 2026 19:47:49 -0400 (EDT) Subject: krb5 commit: Free small client memory leak on OTP failure Message-ID: <20260904234749.F219C1056D8@krbdev.mit.edu> https://github.com/krb5/krb5/commit/82a4224f07ad21c2a3e977c5c4651d7d30c6f1f0 commit 82a4224f07ad21c2a3e977c5c4651d7d30c6f1f0 Author: Greg Hudson Date: Thu Aug 27 19:58:43 2026 -0400 Free small client memory leak on OTP failure When an initial credentials request using FAST OTP fails due to a rejection from the KDC, otp_client_prep_questions() may be called during the processing of the PREAUTH_FAILED response, due to a minor malfunction in the preauth logic (to be fixed separately). When this happens the OTP challenge in the PREAUTH_FAILED padata is decoded into modreq, overwriting and leaking the decoded challenge from the PREAUTH_REQUIRED response. Although we don't expect multiple otp_client_prep_questions() calls when the preauth logic is behaving properly, it could still happen due to unexpected KDC behavior (such as a MORE_PREAUTH_DATA_REQUIRED response). Fix the leak in otp_client_prep_questions() so that it isn't admitted under any KDC behavior. ticket: 9235 (new) tags: pullup target_version: 1.22-next src/lib/krb5/krb/preauth_otp.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/lib/krb5/krb/preauth_otp.c b/src/lib/krb5/krb/preauth_otp.c index 48003da62..5b734a3ef 100644 --- a/src/lib/krb5/krb/preauth_otp.c +++ b/src/lib/krb5/krb/preauth_otp.c @@ -992,7 +992,7 @@ otp_client_prep_questions(krb5_context context, krb5_clpreauth_moddata moddata, krb5_data *encoded_previous_request, krb5_pa_data *pa_data) { - krb5_pa_otp_challenge *chl; + krb5_pa_otp_challenge *chl, **chp = (krb5_pa_otp_challenge **)modreq; krb5_error_code retval; krb5_data tmp; char *json; @@ -1000,13 +1000,17 @@ otp_client_prep_questions(krb5_context context, krb5_clpreauth_moddata moddata, if (modreq == NULL) return ENOMEM; + /* We shouldn't normally be called twice during the same initial + * credentials request, but if we are, free the previous challenge. */ + k5_free_pa_otp_challenge(context, *chp); + *chp = NULL; + /* Decode the challenge. */ tmp = make_data(pa_data->contents, pa_data->length); - retval = decode_krb5_pa_otp_challenge(&tmp, - (krb5_pa_otp_challenge **)modreq); + retval = decode_krb5_pa_otp_challenge(&tmp, chp); if (retval != 0) return retval; - chl = *(krb5_pa_otp_challenge **)modreq; + chl = *chp; /* Remove unsupported tokeninfos. */ retval = filter_supported_tokeninfos(context, chl->tokeninfo); From ghudson at mit.edu Fri Sep 4 20:00:02 2026 From: ghudson at mit.edu (ghudson at mit.edu) Date: Fri, 4 Sep 2026 20:00:02 -0400 (EDT) Subject: krb5 commit [krb5-1.22]: Prevent dangling result in tl_data2berval() Message-ID: <20260905000002.7984D1056F8@krbdev.mit.edu> https://github.com/krb5/krb5/commit/5dbd6ba425eecf76396d2f78b79738983b255c20 commit 5dbd6ba425eecf76396d2f78b79738983b255c20 Author: Greg Hudson Date: Mon Aug 31 17:56:46 2026 -0400 Prevent dangling result in tl_data2berval() If the second malloc() fails in tl_data2berval(), do not leave a dangling freed pointer in *out, or the caller will free it a second time. Reported by Vidal Segura Garc??a. (cherry picked from commit 6a880f5a629ccdfe9e5ecefc46b2186ba69bcc6d) ticket: 9232 version_fixed: 1.22.3 src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c b/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c index 525e8d027..251da025b 100644 --- a/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c +++ b/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c @@ -628,20 +628,24 @@ cleanup: static krb5_error_code tl_data2berval (krb5_tl_data *in, struct berval **out) { - *out = (struct berval *) malloc (sizeof (struct berval)); - if (*out == NULL) - return ENOMEM; + struct berval *bv; - (*out)->bv_len = in->tl_data_length + 2; - (*out)->bv_val = (char *) malloc ((*out)->bv_len); - if ((*out)->bv_val == NULL) { - free (*out); + *out = NULL; + + bv = malloc(sizeof(*bv)); + if (bv == NULL) + return ENOMEM; + bv->bv_len = in->tl_data_length + 2; + bv->bv_val = malloc(bv->bv_len); + if (bv->bv_val == NULL) { + free(bv); return ENOMEM; } - STORE16_INT((*out)->bv_val, in->tl_data_type); - memcpy ((*out)->bv_val + 2, in->tl_data_contents, in->tl_data_length); + STORE16_INT(bv->bv_val, in->tl_data_type); + memcpy(bv->bv_val + 2, in->tl_data_contents, in->tl_data_length); + *out = bv; return 0; } From ghudson at mit.edu Fri Sep 4 20:00:08 2026 From: ghudson at mit.edu (ghudson at mit.edu) Date: Fri, 4 Sep 2026 20:00:08 -0400 (EDT) Subject: krb5 commit [krb5-1.22]: Free small client memory leak on OTP failure Message-ID: <20260905000008.288AA105707@krbdev.mit.edu> https://github.com/krb5/krb5/commit/e689b5d54d90a45f4d03ccbdae40fb4037276ea7 commit e689b5d54d90a45f4d03ccbdae40fb4037276ea7 Author: Greg Hudson Date: Thu Aug 27 19:58:43 2026 -0400 Free small client memory leak on OTP failure When an initial credentials request using FAST OTP fails due to a rejection from the KDC, otp_client_prep_questions() may be called during the processing of the PREAUTH_FAILED response, due to a minor malfunction in the preauth logic (to be fixed separately). When this happens the OTP challenge in the PREAUTH_FAILED padata is decoded into modreq, overwriting and leaking the decoded challenge from the PREAUTH_REQUIRED response. Although we don't expect multiple otp_client_prep_questions() calls when the preauth logic is behaving properly, it could still happen due to unexpected KDC behavior (such as a MORE_PREAUTH_DATA_REQUIRED response). Fix the leak in otp_client_prep_questions() so that it isn't admitted under any KDC behavior. (cherry picked from commit 82a4224f07ad21c2a3e977c5c4651d7d30c6f1f0) ticket: 9235 version_fixed: 1.22.3 src/lib/krb5/krb/preauth_otp.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/lib/krb5/krb/preauth_otp.c b/src/lib/krb5/krb/preauth_otp.c index 07ffc15c2..abc171f5b 100644 --- a/src/lib/krb5/krb/preauth_otp.c +++ b/src/lib/krb5/krb/preauth_otp.c @@ -989,7 +989,7 @@ otp_client_prep_questions(krb5_context context, krb5_clpreauth_moddata moddata, krb5_data *encoded_previous_request, krb5_pa_data *pa_data) { - krb5_pa_otp_challenge *chl; + krb5_pa_otp_challenge *chl, **chp = (krb5_pa_otp_challenge **)modreq; krb5_error_code retval; krb5_data tmp; char *json; @@ -997,13 +997,17 @@ otp_client_prep_questions(krb5_context context, krb5_clpreauth_moddata moddata, if (modreq == NULL) return ENOMEM; + /* We shouldn't normally be called twice during the same initial + * credentials request, but if we are, free the previous challenge. */ + k5_free_pa_otp_challenge(context, *chp); + *chp = NULL; + /* Decode the challenge. */ tmp = make_data(pa_data->contents, pa_data->length); - retval = decode_krb5_pa_otp_challenge(&tmp, - (krb5_pa_otp_challenge **)modreq); + retval = decode_krb5_pa_otp_challenge(&tmp, chp); if (retval != 0) return retval; - chl = *(krb5_pa_otp_challenge **)modreq; + chl = *chp; /* Remove unsupported tokeninfos. */ retval = filter_supported_tokeninfos(context, chl->tokeninfo);