Created attachment 18994 [details] original report Tristan (TristanInSec@gmail.com) reports (as attached): The kpasswd request parser in `source4/kdc/kpasswd-service.c` miscalculates the length of the encrypted data portion. The kpasswd packet format (RFC 3244) is: [2-byte length][2-byte version][2-byte AP-REQ length][AP-REQ][encrypted data] \_________________ HEADER_LEN = 6 __________________/ At line 140, the encrypted data length is computed as: enc_data_len = len - ap_req_len; // WRONG: includes HEADER_LEN The correct calculation: enc_data_len = len - HEADER_LEN - ap_req_len; Since the blob starts at offset `HEADER_LEN + ap_req_len` but its length includes the 6 header bytes, it extends 6 bytes past the end of the request buffer. This blob is passed to `gensec_unwrap()` at line 270, which reads the full contents including the OOB bytes. ## Example With `len=100` and `ap_req_len=50`: - `enc_data_len = 100 - 50 = 50` (should be 44) - Blob starts at offset 56, extends to offset 105 - Buffer ends at offset 99 - 6 bytes read past buffer end ## Impact 6-byte heap OOB read. The extra bytes are processed by the GENSEC layer during decryption. The decryption will fail (corrupted ciphertext), but the read occurs before the failure. If the buffer sits at a page boundary, this can crash the AD DC KDC process.
Tristan suggests CVSS 3.1: 4.3 (AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N) which is saying an unprivileged user can easily leak a little bit of process memory. It is not clear to me how the extra six bytes might be revealed to the user after gensec_unwrap() fails. The other claim remains: > If the buffer sits at a page boundary, this can crash the AD DC KDC process.
(In reply to Douglas Bagnall from comment #1) > It is not clear to me how the extra six bytes might be revealed to the user after gensec_unwrap() fails. In particular, from line 350 code = smb_krb5_mk_error(kdc->smb_krb5_context->krb5_context, KRB5KDC_ERR_NONE + error_code, NULL, /* e_text */ &k_dec_data, NULL, /* client */ server_principal, &k_enc_data); krb5_free_principal(kdc->smb_krb5_context->krb5_context, server_principal); if (code != 0) { DBG_ERR("Failed to create krb5 error reply: %s\n", error_message(code)); goto done; } enc_data_blob = data_blob_talloc(tmp_ctx, k_enc_data.data, k_enc_data.length); enc_data_blob is overwritten with k_enc_data. Tracing through, I do not see the trailing memory from the earlier enc_data_blob in *reply.
Good analysis. You are right -- I had not traced past the gensec_unwrap() failure. The enc_data_blob is overwritten at line 364 with the Kerberos error reply from smb_krb5_mk_error(), so the 6 OOB bytes never reach the client. C:L was wrong in my original scoring. The residual risk is the OOB read itself: the 6 bytes are always read by gensec_unwrap (AC:L), but since the data does not leak, the only impact is DoS if the allocation sits at a page boundary (which would make it AC:H for the crash). The off-by-6 calculation is still a clear bug (enc_data_len = len - ap_req_len should be enc_data_len = len - HEADER_LEN - ap_req_len), and in a security-sensitive component like the KDC, any OOB read is worth patching regardless of whether it meets the advisory threshold. Happy if it is fixed as a regular bug.
(In reply to TristanInSec from comment #3) We think usually gensec_unwrap() does not fail (the KRB_PRIV parser in Heimdal doesn't read the trailing bytes, it follows the ASN.1 in the packet).
(In reply to Douglas Bagnall from comment #4) The ASN.1-bounded parsing is a fair point for the common case. Two things though: 1. "Usually" -- are there GENSEC mechanisms or code paths where the full blob length is consumed rather than the ASN.1-defined length? 2. Regardless of the current consumer, the DATA_BLOB carries the wrong length. Any future code that trusts .length (a copy, a log, a different GENSEC backend) would inherit the off-by-6. For a one-line fix in the KDC, the cost of not fixing it is higher than fixing it.
(In reply to TristanInSec from comment #5) I am not sure other backends matter, given kpasswd_process says: status = gensec_start_mech_by_name(gensec_security, "krb5"); and is itself only called from source4/kdc/kdc-heimdal.c. But we shouldn't care about that. If a crafted packet can crash the server, we are going to fix it as a security bug anyway.
Created attachment 19008 [details] draft advisory
Created attachment 19009 [details] patch for master
Created attachment 19010 [details] test that fails to crash I have added an advisory and patch, and a test that never actually causes a crash. It may be that memory allocation patterns on my machine never allow a segfault, or it could be that I am just not trying properly.
Tristan, how do you want to be credited? Do you want us to mention a surname or company name?
(In reply to Douglas Bagnall from comment #10) Hi, Thank you for asking, it is greatly appreciated. Could you please use: "Tristan Madani" Or, if a longer attribution is appropriate: "Tristan Madani (@TristanInSec), Talence Security" If you provide backlinks, the website is: https://talencesecurity.com Best, Tristan
Created attachment 19077 [details] advisory v2 (adding CVE, credit)
Comment on attachment 19009 [details] patch for master >From 85cc88b97ef8fa4f54d9432c2730d748feb7b8b0 Mon Sep 17 00:00:00 2001 >From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Date: Sun, 31 May 2026 12:48:11 +1200 >Subject: [PATCH] kdc:kpasswd: calculate correct size for password blob > >We were making the enc_data_blob 6 bytes too big. > >Its payload is an ASN.1 structure that knows its own size, so the >extra bytes are not usually read by Heimdal, but a crafted packet >could force them to be read. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=16087 > >Reported-by: Tristan <TristanInSec@gmail.com> >Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >--- > source4/kdc/kpasswd-service.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/source4/kdc/kpasswd-service.c b/source4/kdc/kpasswd-service.c >index c671eb46d07..0284fb4f133 100644 >--- a/source4/kdc/kpasswd-service.c >+++ b/source4/kdc/kpasswd-service.c >@@ -137,7 +137,7 @@ kdc_code kpasswd_process(struct kdc_server *kdc, > > ap_req_blob = data_blob_const(&request->data[HEADER_LEN], ap_req_len); > >- enc_data_len = len - ap_req_len; >+ enc_data_len = len - (ap_req_len + HEADER_LEN); > enc_data_blob = data_blob_const(&request->data[HEADER_LEN + ap_req_len], > enc_data_len); > >-- >2.43.0 >
patch for master applies back to 4.7.
adding vendors here. scheduled release 2026-07-28 10:00 UTC.
Probably a typo also here, CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:N/I:N/A:H results in a 5.3 score, not 6.5
Created attachment 19122 [details] advisory with fixed score value
(In reply to Björn Jacke from comment #17) I think the typo might be more in claiming /AC:H/ rather than /AC:L/ (which would be 6.5), but whichever.
This bug was referenced in samba v4-24-stable (Release samba-4.24.5): 1ab79135f5b803c99b06289378d090f69821f066
This bug was referenced in samba v4-22-stable (Release samba-4.22.11): 5ce6e63978f62daafaab44ee77284d72a0603225
This bug was referenced in samba v4-23-stable (Release samba-4.23.10): 4fb7188bd7cc1e15d88c58541a561ddaa3ae0a37
This bug was referenced in samba v4-22-test: 5ce6e63978f62daafaab44ee77284d72a0603225
This bug was referenced in samba v4-24-test: d25f3ff0834daeb612e454e84ac325ed743f38ea
This bug was referenced in samba v4-23-test: 91c9696e2dada5160fea5f32764ca5ba7271284c
This bug was referenced in samba v4-24-test: 1ab79135f5b803c99b06289378d090f69821f066
This bug was referenced in samba v4-23-test: 4fb7188bd7cc1e15d88c58541a561ddaa3ae0a37
This bug was referenced in samba master: 7a8fb86ae8cc907f2d26049dbf71c561c40a8de6
This bug was referenced in samba v4-23-stable (Release samba-4.23.11): 91c9696e2dada5160fea5f32764ca5ba7271284c
This bug was referenced in samba v4-24-stable (Release samba-4.24.6): d25f3ff0834daeb612e454e84ac325ed743f38ea