[20552] in Kerberos_V5_Development
KDC audit plugin potential use-after-free
daemon@ATHENA.MIT.EDU (=?UTF-8?B?0JDQu9C10LrRgdCw0L3QtNGA)
Tue Dec 9 23:38:14 2025
MIME-Version: 1.0
From: =?UTF-8?B?0JDQu9C10LrRgdCw0L3QtNGAINCR0LDQutCw0L3QvtCy0YHQutC40Lk=?=
<skotttt228@gmail.com>
Date: Tue, 9 Dec 2025 17:58:06 +0300
Message-ID: <CAEyN6c3L4BG4Dz+XZZb3x1y1nkM_M16SCAC43_uDTNtykSehhQ@mail.gmail.com>
To: krbdev@mit.edu
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit
Errors-To: krbdev-bounces@mit.edu
Hello! While working with audit plugin I found 2 use-after-free issues
1. So right before passing a state.reply to a kau_as_req() audit function
it frees state.reply.enc_part.ciphertext.data so from the plugin side we
can use-after-free (which happened to me:))
https://github.com/krb5/krb5/blob/master/src/kdc/do_as_req.c#L334
I guess we should free after passing the struct to the kau_as_req()
This behavior occurs for both AS_REP and TGS_REP
2. For TGS_REP there also an issue
https://github.com/krb5/krb5/blob/master/src/kdc/do_tgs_req.c#L1087 - here
reply.ticket is a reference to a ticket_reply
https://github.com/krb5/krb5/blob/master/src/kdc/do_tgs_req.c#L1125 - here
reply is passed to an audit plugin in a kau_tgs_req()
https://github.com/krb5/krb5/blob/master/src/kdc/do_tgs_req.c#L1129 -
cleanup happens here
However from the audit plugin perspective ticket.enc_part is already free'd
So if the operation is TGS_REP and ticket is not NULL => enc_part field is
now use-after-free
here's valgrind:
==7== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
==16== Invalid read of size 1
==16== at 0x5558591: <hex::BytesToHexChars as
core::iter::traits::iterator::Iterator>::next (in
/usr/lib/x86_64-linux-gnu/krb5/plugins/audit/libkdc_audit.so)
==16== by 0x5556DA1: <alloc::string::String as
core::iter::traits::collect::FromIterator<char>>::from_iter (in
/usr/lib/x86_64-linux-gnu/krb5/plugins/audit/libkdc_audit.so)
==16== by 0x5551D25: <krb5_audit_common::krb_types::enc_part::EncPart as
krb5_audit_common::krb_types::common::FromRef<krb5_audit_common::bindings::_krb5_enc_data>>::from_ref
(in /usr/lib/x86_64-linux-gnu/k
rb5/plugins/audit/libkdc_audit.so)
==16== by 0x55574D1: <krb5_audit_common::krb_types::ticket::Ticket as
krb5_audit_common::krb_types::common::FromRef<krb5_audit_common::bindings::_krb5_ticket>>::from_ref
(in /usr/lib/x86_64-linux-gnu/krb5/p
lugins/audit/libkdc_audit.so)
==16== by 0x554E2A3:
<krb5_audit_common::krb_types::kdc_rep::KdcRep_Trace as
krb5_audit_common::krb_types::common::FromRef<krb5_audit_common::bindings::_krb5_kdc_rep>>::from_ref
(in /usr/lib/x86_64-linux-gn
u/krb5/plugins/audit/libkdc_audit.so)
==16== by 0x554DAA3: <krb5_audit_common::krb_types::kdc_rep::KdcRep as
krb5_audit_common::krb_types::common::FromRef<krb5_audit_common::bindings::_krb5_kdc_rep>>::from_ref
(in /usr/lib/x86_64-linux-gnu/krb5
/plugins/audit/libkdc_audit.so)
==16== by 0x554009C: kdc_audit::kdc_state::Krb5AuditState::new (in
/usr/lib/x86_64-linux-gnu/krb5/plugins/audit/libkdc_audit.so)
==16== by 0x5542C88: audit_process_request (in
/usr/lib/x86_64-linux-gnu/krb5/plugins/audit/libkdc_audit.so)
==16== by 0x120103: ??? (in /usr/sbin/krb5kdc)
==16== by 0x112543: ??? (in /usr/sbin/krb5kdc)
==16== Address 0x4cd8fe0 is 0 bytes inside a block of size 377 free'd
==16== at 0x484417B: free (vg_replace_malloc.c:872)
==16== by 0x114935: ??? (in /usr/sbin/krb5kdc)
==16== by 0x110985: ??? (in /usr/sbin/krb5kdc)
==16== by 0x124CAD: ??? (in /usr/sbin/krb5kdc)
==16== by 0x49C4137: verto_fire (in
/usr/lib/x86_64-linux-gnu/libverto.so.1.0.0)
==16== by 0x5048632: ev_invoke_pending (in
/usr/lib/x86_64-linux-gnu/libev.so.4.0.0)
==16== by 0x504BE70: ev_run (in /usr/lib/x86_64-linux-gnu/libev.so.4.0.0)
==16== by 0x10F7D6: ??? (in /usr/sbin/krb5kdc)
==16== by 0x49EF249: (below main) (libc_start_call_main.h:58)
==16== Block was alloc'd at
==16== at 0x48417B4: malloc (vg_replace_malloc.c:381)
==16== by 0x48E706C: krb5_encrypt_helper (in
/usr/lib/x86_64-linux-gnu/libkrb5.so.3.3)
==16== by 0x48E73BC: krb5_encrypt_tkt_part (in
/usr/lib/x86_64-linux-gnu/libkrb5.so.3.3)
==16== by 0x113B77: ??? (in /usr/sbin/krb5kdc)
==16== by 0x110985: ??? (in /usr/sbin/krb5kdc)
==16== by 0x124CAD: ??? (in /usr/sbin/krb5kdc)
==16== by 0x49C4137: verto_fire (in
/usr/lib/x86_64-linux-gnu/libverto.so.1.0.0)
==16== by 0x5048632: ev_invoke_pending (in
/usr/lib/x86_64-linux-gnu/libev.so.4.0.0)
==16== by 0x504BE70: ev_run (in /usr/lib/x86_64-linux-gnu/libev.so.4.0.0)
==16== by 0x10F7D6: ??? (in /usr/sbin/krb5kdc)
==16==
In my code I used workarounds to not parse reply.ticket.enc_part for
TGS_REP and reply.enc_part.cipher when AS_REP/TGS_REP. I'm not sure if that
is an issue or a safety design not to access these fields
Thanks in advance!
_______________________________________________
krbdev mailing list krbdev@mit.edu
https://mailman.mit.edu/mailman/listinfo/krbdev