This bug is due to a double-free in source3/librpc/crypto/gse.c where
gse_ctx->k5ctx is freed twice if gse_context_init fails and the err_out
path is taken.
The beginning of gse_context_init calls talloc_set_destructor to call
gse_context_destructor:
talloc_set_destructor((TALLOC_CTX *)gse_ctx,
gse_context_destructor);
This gse_context_destructor callback function is triggered by calls to
TALLOC_FREE(gse_ctx) and frees pointers stored in the gse_ctx structure
including gse_ctx->k5ctx:
if (gse_ctx->k5ctx) {
if (gse_ctx->ccache) {
krb5_cc_close(gse_ctx->k5ctx, gse_ctx->ccache);
gse_ctx->ccache = NULL;
}
if (gse_ctx->keytab) {
krb5_kt_close(gse_ctx->k5ctx, gse_ctx->keytab);
gse_ctx->keytab = NULL;
}
krb5_free_context(gse_ctx->k5ctx);
gse_ctx->k5ctx = NULL;
}
However, if gse_context_init fails and takes the err_out path,
gse_ctx->k5ctx is freed without setting that pointer to NULL and then
immediately calls TALLOC_FREE(gse_ctx) which then attempts to free
gse_ctx->k5ctx a second time:
err_out:
if (gse_ctx->k5ctx) {
krb5_free_context(gse_ctx->k5ctx);
}
TALLOC_FREE(gse_ctx);
This results in the following double-free stack trace:
(gdb) bt
#0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
#1 0x00007ffff7443859 in __GI_abort () at abort.c:79
#2 0x00007ffff74ae3ee in __libc_message (action=action@entry=do_abort,
fmt=fmt@entry=0x7ffff75d8285 "%s\n") at ../sysdeps/posix/libc_fatal.c:155
#3 0x00007ffff74b647c in malloc_printerr (str=str@entry=0x7ffff75da5d0
"free(): double free detected in tcache 2") at malloc.c:5347
#4 0x00007ffff74b80ed in _int_free (av=0x7ffff7609b80 <main_arena>,
p=0x5555555ce2c0, have_lock=0) at malloc.c:4201
#5 0x00007ffff6cc29f9 in krb5_free_context (context=0x5555555cdcd0) at
../../source4/heimdal/lib/krb5/context.c:595
#6 0x00007ffff73e75d1 in gse_context_destructor (ptr=ptr@entry=0x5555555cdc50)
at ../../source3/librpc/crypto/gse.c:84
#7 0x00007ffff776553e in _tc_free_internal (tc=0x5555555cdbf0,
location=0x7ffff73f2480 "../../source3/librpc/crypto/gse.c:241") at
../../talloc.c:1157
#8 0x00007ffff73e826c in gse_context_init
(mem_ctx=mem_ctx@entry=0x5555555cdb60, do_sign=<optimized out>,
do_seal=<optimized out>, add_gss_c_flags=<optimized out>,
_gse_ctx=_gse_ctx@entry=0x7fffffffd500,
ccache_name=<optimized out>) at ../../source3/librpc/crypto/gse.c:241
#9 0x00007ffff73e8433 in gse_init_client (ccache_name=0x0, realm=<optimized
out>, username=<optimized out>, password=<optimized out>, _gse_ctx=<synthetic
pointer>, add_gss_c_flags=<optimized out>,
service=0x5555555ccdf0 "cifs", server=0x5555555ccfb0 "freenas",
do_seal=<optimized out>, do_sign=<optimized out>, mem_ctx=0x5555555cdb60) at
../../source3/librpc/crypto/gse.c:268
#10 gensec_gse_client_start (gensec_security=0x5555555cdb60) at
../../source3/librpc/crypto/gse.c:786
#11 0x00007ffff7390453 in gensec_start_mech (gensec_security=0x5555555cdb60) at
../../auth/gensec/gensec_start.c:743
#12 gensec_start_mech (gensec_security=0x5555555cdb60) at
../../auth/gensec/gensec_start.c:704
#13 0x00007ffff7387822 in gensec_spnego_client_negTokenInit_step
(gensec_security=0x5555555c9b70, spnego_state=0x5555555cc1b0, n=0x5555555cd4a0,
spnego_in=<optimized out>, last_status=...,
in_mem_ctx=<optimized out>, in_next=0x5555555cd3f8) at
../../auth/gensec/spnego.c:633
#14 0x00007ffff7387e02 in gensec_spnego_client_negTokenInit_start
(gensec_security=0x5555555c9b70, spnego_state=0x5555555cc1b0, n=0x5555555cd4a0,
spnego_in=0x5555555cd368, in_mem_ctx=0x5555555cd340,
in_next=0x5555555cd3f8) at ../../auth/gensec/spnego.c:537
#15 0x00007ffff7388b84 in gensec_spnego_update_pre (req=0x5555555cd190) at
../../auth/gensec/spnego.c:1943
#16 gensec_spnego_update_send (mem_ctx=<optimized out>, ev=0x5555555aee90,
gensec_security=<optimized out>, in=...) at ../../auth/gensec/spnego.c:1741
#17 0x00007ffff738f3b0 in gensec_update_send (mem_ctx=<optimized out>,
ev=0x5555555aee90, gensec_security=0x5555555c9b70, in=...) at
../../auth/gensec/gensec.c:449
#18 0x00007ffff7f6dba6 in cli_session_setup_gensec_local_next
(req=0x5555555c9d90) at ../../source3/libsmb/cliconnect.c:997
#19 0x00007ffff7f6f520 in cli_session_setup_gensec_send
(target_service=0x7ffff7fa478e "cifs", target_hostname=0x5555555ca480
"freenas", creds=0x5555555adf90, cli=0x5555555adf90, ev=0x5555555aee90,
mem_ctx=<optimized out>) at ../../source3/libsmb/cliconnect.c:977
#20 cli_session_setup_spnego_send (creds=0x5555555adf90, cli=0x5555555adf90,
ev=0x5555555aee90, mem_ctx=<optimized out>) at
../../source3/libsmb/cliconnect.c:1346
#21 cli_session_setup_creds_send (mem_ctx=mem_ctx@entry=0x5555555aee90,
ev=ev@entry=0x5555555aee90, cli=cli@entry=0x5555555adf90,
creds=creds@entry=0x5555555b4380) at ../../source3/libsmb/cliconnect.c:1505
#22 0x00007ffff7f6fcad in cli_session_setup_creds (cli=0x5555555adf90,
creds=creds@entry=0x5555555b4380) at ../../source3/libsmb/cliconnect.c:1843
#23 0x00007ffff7f8ca57 in do_connect (ctx=ctx@entry=0x5555555aae90,
server=<optimized out>, server@entry=0x5555555b4790 "freenas",
share=share@entry=0x555555571183 "IPC$", auth_info=0x5555555b42f0,
force_encrypt=<optimized out>, max_protocol=max_protocol@entry=13, port=0,
name_type=32, pcli=0x7fffffffd8a0) at ../../source3/libsmb/clidfs.c:236
#24 0x00007ffff7f8cfa8 in cli_cm_connect (ctx=ctx@entry=0x5555555aae90,
referring_cli=referring_cli@entry=0x0, server=server@entry=0x5555555b4790
"freenas", share=share@entry=0x555555571183 "IPC$",
auth_info=<optimized out>, force_encrypt=force_encrypt@entry=false,
max_protocol=13, port=0, name_type=32, pcli=0x7fffffffd900) at
../../source3/libsmb/clidfs.c:339
#25 0x00007ffff7f8d13f in cli_cm_open (ctx=0x5555555aae90, referring_cli=0x0,
server=0x5555555b4790 "freenas", share=0x555555571183 "IPC$",
auth_info=<optimized out>, force_encrypt=<optimized out>,
max_protocol=13, port=0, name_type=32, pcli=0x55555557c398 <cli>) at
../../source3/libsmb/clidfs.c:441
#26 0x000055555555edc0 in do_host_query (query_host=0x5555555b4790 "freenas")
at ../../source3/client/client.c:6702
#27 main (argc=<optimized out>, argv=<optimized out>) at
../../source3/client/client.c:6702
(gdb)
When explicitly setting gse_ctx->k5ctx to NULL after the free, this
crash no longer occurs and I can now access SMB shares successfully:
err_out:
if (gse_ctx->k5ctx) {
krb5_free_context(gse_ctx->k5ctx);
gse_ctx->k5ctx = NULL;
}
TALLOC_FREE(gse_ctx);
This bug appears to have been fixed upstream by removing the explicit
krb5_free_context call here and depending on gse_context_destructor to
free the k5ctx member pointer:
err_out:
TALLOC_FREE(gse_ctx);
--
You received this bug notification because you are a member of Ubuntu
Bugs, which is subscribed to Ubuntu.
https://bugs.launchpad.net/bugs/1892145
Title:
smbclient cannot connect anonymously in Kerberos context (freeipa)
To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/samba/+bug/1892145/+subscriptions
--
ubuntu-bugs mailing list
[email protected]
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs